package com.zbkj.crmeb.store.utilService;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import com.crmeb.core.common.CommonResult;
import com.crmeb.core.exception.ExceptionCodeEnum;
import com.google.gson.JsonObject;
import com.taobao.pac.sdk.cp.dataobject.request.MODUAN_ORDER_CREATE.request;
import com.utils.*;
import com.utils.lianlianpay.client.LLianPayClient;
import com.utils.lianlianpay.dto.confirm.SecuredConfirmOrderInfo;
import com.utils.lianlianpay.dto.confirm.SecuredConfirmOriginalOrderInfo;
import com.utils.lianlianpay.dto.confirm.SecuredConfirmParams;
import com.utils.lianlianpay.dto.confirm.SecuredConfirmResult;
import com.utils.monitor.DingMsgEnum;
import com.utils.monitor.DingTalkMsgUtil;
import com.zbkj.crmeb.agent.model.Agent;
import com.zbkj.crmeb.chant.service.ChannelDiscountPackageService;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.store.model.*;
import com.zbkj.crmeb.store.response.StoreProductCartProductInfoResponse;
import com.zbkj.crmeb.store.service.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.common.PageParamRequest;
import com.constants.Constants;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.utils.RedisUtil;
import com.zbkj.crmeb.agent.model.AgentFreezeBill;
import com.zbkj.crmeb.agent.service.AgentFreezeBillService;
import com.zbkj.crmeb.bill.model.MerFreezeBill;
import com.zbkj.crmeb.bill.service.MerFreezeBillService;
import com.zbkj.crmeb.chant.model.ChannelActivity;
import com.zbkj.crmeb.chant.model.ChannelMemberLevel;
import com.zbkj.crmeb.chant.model.ChannelMerchant;
import com.zbkj.crmeb.chant.model.ChannelPicking;
import com.zbkj.crmeb.chant.model.MerchantAddress;
import com.zbkj.crmeb.chant.service.ChannelPickingService;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.chant.service.MerchantAddressService;
import com.zbkj.crmeb.express.service.FirstLogisticsCostService;
import com.zbkj.crmeb.front.request.OrderCreateRequest;
import com.zbkj.crmeb.front.response.ComputeOrderResponse;
import com.zbkj.crmeb.front.response.ConfirmOrderResponse;
import com.zbkj.crmeb.front.response.PriceGroupResponse;
import com.zbkj.crmeb.front.service.ProductService;
import com.zbkj.crmeb.front.vo.OrderAgainItemVo;
import com.zbkj.crmeb.front.vo.OrderAgainVo;
import com.zbkj.crmeb.front.vo.VipDiscountVo;
import com.zbkj.crmeb.marketing.model.StoreCouponUser;
import com.zbkj.crmeb.marketing.request.FrontStoreCouponUserRequest;
import com.zbkj.crmeb.marketing.response.StoreCouponUserResponse;
import com.zbkj.crmeb.marketing.service.StoreCouponService;
import com.zbkj.crmeb.marketing.service.StoreCouponUserService;
import com.zbkj.crmeb.member.model.MerchantMemberBenefits;
import com.zbkj.crmeb.member.model.StoreProductDiscount;
import com.zbkj.crmeb.member.service.IMerchantMemberBenefitsService;
import com.zbkj.crmeb.member.service.IStoreProductDiscountService;
import com.zbkj.crmeb.merchant.api.service.FrontCouponUserService;
import com.zbkj.crmeb.order.AbstractStoreOrderService;
import com.zbkj.crmeb.order.StoreOrderFactory;
import com.zbkj.crmeb.store.request.StoreOrderSearchRequest;
import com.zbkj.crmeb.store.response.StoreCartResponse;
import com.zbkj.crmeb.store.response.StoreOrderCountItemResponse;
import com.zbkj.crmeb.store.vo.CalculatePriceVo;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.model.SystemStore;
import com.zbkj.crmeb.system.response.SystemGroupDataOrderStatusPicResponse;
import com.zbkj.crmeb.system.service.SystemConfigService;
import com.zbkj.crmeb.system.service.SystemGroupDataService;
import com.zbkj.crmeb.system.service.SystemStoreService;
import com.zbkj.crmeb.user.model.User;
import com.zbkj.crmeb.user.model.UserAddress;
import com.zbkj.crmeb.user.model.UserMemberRecord;
import com.zbkj.crmeb.user.request.UserOperateFundsRequest;
import com.zbkj.crmeb.user.service.UserAddressService;
import com.zbkj.crmeb.user.service.UserMemberRecordService;
import com.zbkj.crmeb.user.service.UserService;

import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import sun.management.resources.agent;

import javax.annotation.Resource;


/**
 * @author stivepeim
 * @title: OrderUtils
 * @projectName crmeb
 * @description: 订单工具类
 * @date 2020/7/2019:29
 */
@Service
@Slf4j
public class OrderUtils {
    @Autowired
    private SystemStoreService systemStoreService;
    @Autowired
    private UserService userService;
    @Autowired
    private StoreOrderStatusService storeOrderStatusService;
    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private UserAddressService userAddressService;
    @Autowired
    private StoreCouponUserService storeCouponUserService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private ChannelGroupBookingService channelGroupBookingService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private StoreOrderService storeOrderService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private StoreCartService storeCartService;
    @Autowired
    private SystemGroupDataService systemGroupDataService;
    @Autowired
    private TemplatesCostConfigService templatesCostConfigService;
    @Autowired
    private MarkupRateService markupRateService;
    @Autowired
    FirstLogisticsCostService firstLogisticsCostService;
    @Autowired
    ProductUtil productUtil;
    @Autowired
    IChannelMerchantService channelMerchantService;
    @Autowired
    PriceUtil priceUtil;
    @Autowired
    ProductService productService;
    @Autowired
    MerchantAddressService merchantAddressService;
    @Autowired
    StoreCouponService storeCouponService;
    @Autowired
    private MerFreezeBillService merFreezeBillService;
    @Autowired
    private FrontCouponUserService frontCouponUserService;
    @Autowired
    private AgentFreezeBillService agentFreezeBillService;
    @Autowired
    StoreOrderFactory storeOrderFactory;
    @Autowired
    private SupplierService supplierService;
    @Autowired
    private UserMemberRecordService userMemberRecordService;
    @Autowired
    private IMerchantMemberBenefitsService merchantMemberBenefitsService;
    @Autowired
    private IStoreProductDiscountService storeProductDiscountService;
    @Autowired
    private StoreOrderInfoPickingService storeOrderInfoPickingService;
    @Autowired
    private ChannelPickingService channelPickingService;
    @Autowired
    private ChannelFreeShippingActivityService channelFreeShippingActivityService;
    @Autowired
    private ChannelDiscountPackageService channelDiscountPackageService;
    @Resource
    private PersonPayLimitUtils personPayLimitUtils;

    @Value("${order.checkIdCard}")
    private boolean checkIdCard;
    @Value("${order.lianlianMerIds}")
    private List<Integer> lianlianMerIds;
    @Value("${order.wxMerIds}")
    private List<Integer> wxMerIds;
    @Value("${order.wxHKMerIds}")
    private List<Integer> wxHKMerIds;
    @Value("${order.adapayDegreeMerIds}")
    private List<Integer> adapayDegreeMerIds;
    @Value("${order.adapayCnMerIds}")
    private List<Integer> adapayCnMerIds;

    // 组装数据给前端使用
    public OrderAgainVo tidyOrder(StoreOrder storeOrder, boolean detail, boolean isPic) {
        OrderAgainVo orderAgainVoResult = new OrderAgainVo();
        orderAgainVoResult.setStoreOrder(storeOrder);
        List<StoreOrderInfoVo> existOrderList = null;
        if (detail && storeOrder.getId() > 0) {
            existOrderList = getOrderInfoVoList(storeOrder);
            orderAgainVoResult.setCartInfo(existOrderList);
        }
        OrderAgainItemVo status = null;
        if (storeOrder.getId() > 0
                && storeOrder.getPayType().equals(Constants.PAY_TYPE_OFFLINE)
                && storeOrder.getStatus() >= 2) {
            status = new OrderAgainItemVo(9, "线下付款", "等待商家处理，请耐心等候");
        } else if (!storeOrder.getPaid()) {
            status = new OrderAgainItemVo(0, "未支付", "订单未支付");
            // 系统预设取消订单时间段
            List<String> configKeys = new ArrayList<>();
            configKeys.add("order_cancel_time" + "_" + storeOrder.getMerId());
            configKeys.add("order_activity_time");
            configKeys.add("order_bargain_time");
            configKeys.add("order_seckill_time");
            configKeys.add("order_pink_time");
            List<String> configValues = systemConfigService.getValuesByKes(configKeys);
            // 拼团秒杀砍价逻辑处理
            String tempTime = null;
            Date timeSpace = null;
//            if(storeOrder.getPinkId() > 0 || storeOrder.getCombinationId() > 0){
//                tempTime = configValues.get(4).length() > 0 ? configValues.get(4) : configValues.get(1);
//                timeSpace = DateUtil.addSecond(storeOrder.getCreateTime(),Integer.parseInt(tempTime) * 3600);
//            }else if(storeOrder.getSeckillId() > 0){
//                tempTime = configValues.get(3).length() > 0 ? configValues.get(3) : configValues.get(1);
//                timeSpace = DateUtil.addSecond(storeOrder.getCreateTime(), Integer.parseInt(tempTime) * 3600);
//            }else if(storeOrder.getBargainId() > 0){
//                tempTime = configValues.get(2).length() > 0 ? configValues.get(2) : configValues.get(1);
//                timeSpace = DateUtil.addSecond(storeOrder.getCreateTime(), Integer.parseInt(tempTime) * 3600);
//            }else{ // 非 营销活动购买处理
            timeSpace = DateUtil.addSecond(storeOrder.getCreateTime(), Double.valueOf(configValues.get(0)).intValue() * 3600);
//            }
            status.setMsg("请在" + DateUtil.dateToStr(timeSpace, Constants.DATE_FORMAT) + "前完成支付");
        } else if (storeOrder.getRefundStatus() == 1) {
            status = new OrderAgainItemVo(-1, "申请退款中", "商家审核中,请耐心等待");
        } else if (storeOrder.getRefundStatus() == 2) {
            status = new OrderAgainItemVo(-2, "已退款", "已为您退款,感谢您的支持");
        } else if (storeOrder.getStatus() == 0) {
            // todo 秒杀后面在这添加判断
            status = new OrderAgainItemVo(1, "未发货", "商家未发货,请耐心等待");
        } else if (storeOrder.getStatus() == 1) { // 待收货处理
            // 待收货
            if (null != storeOrder.getDeliveryType() && storeOrder.getDeliveryType().equals(Constants.ORDER_STATUS_STR_SPIKE_KEY)) { // 送货
                StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
                storeOrderStatus.setOid(storeOrder.getId());
                storeOrderStatus.setChangeType(Constants.ORDER_LOG_DELIVERY);
                List<StoreOrderStatus> sOrderStatusResults = storeOrderStatusService.getByEntity(storeOrderStatus);
                if (sOrderStatusResults.size() > 0) {
                    String DateStr = DateUtil.dateToStr(sOrderStatusResults.get(sOrderStatusResults.size() - 1).getCreateTime(), Constants.DATE_FORMAT);
                    status = new OrderAgainItemVo(2, "待收货", DateStr + "服务商已送货");
                }
            } else if (null != storeOrder.getDeliveryType() && storeOrder.getDeliveryType().equals(Constants.ORDER_LOG_EXPRESS)) {
                StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
                storeOrderStatus.setOid(storeOrder.getId());
                storeOrderStatus.setChangeType(Constants.ORDER_LOG_EXPRESS);
                List<StoreOrderStatus> sOrderStatusResults = storeOrderStatusService.getByEntity(storeOrderStatus);
                if (sOrderStatusResults.size() > 0) {
                    String DateStr = DateUtil.dateToStr(sOrderStatusResults.get(sOrderStatusResults.size() - 1).getCreateTime(), Constants.DATE_FORMAT);
                    status = new OrderAgainItemVo(2, "待收货", DateStr + "服务商已送货");
                }
            } else {
                StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
                storeOrderStatus.setOid(storeOrder.getId());
                storeOrderStatus.setChangeType(Constants.ORDER_LOG_DELIVERY_VI);
                List<StoreOrderStatus> sOrderStatusResults = storeOrderStatusService.getByEntity(storeOrderStatus);
                if (sOrderStatusResults.size() > 0) {
                    String DateStr = DateUtil.dateToStr(sOrderStatusResults.get(sOrderStatusResults.size() - 1).getCreateTime(), Constants.DATE_FORMAT);
                    status = new OrderAgainItemVo(2, "待收货", DateStr + "服务商已虚拟发货");
                }
            }
        } else if (storeOrder.getStatus() == 2) {
            status = new OrderAgainItemVo(3, "待评价", "已收货,快去评价一下吧");

        } else if (storeOrder.getStatus() == 3) {
            status = new OrderAgainItemVo(4, "交易完成", "'交易完成,感谢您的支持");
        }
        // 支付方式
        if (status != null) {
            if (null != storeOrder.getStatus()) {
                status.setPayType(getOrderPayTypeStr(storeOrder.getPayType()));
            }
            if (StringUtils.isNotBlank(storeOrder.getDeliveryType())) {
                status.setDeliveryType(StringUtils.isNotBlank(storeOrder.getDeliveryType()) ? storeOrder.getDeliveryType() : "其他方式");
            }
        }

        orderAgainVoResult.setStatus(status);
        orderAgainVoResult.setPayTime(null != storeOrder.getPayTime() ? storeOrder.getPayTime().toString() : storeOrder.getCreateTime().toString());
        orderAgainVoResult.setAddTime(null != storeOrder.getCreateTime() ? storeOrder.getCreateTime().toString() : "");
        orderAgainVoResult.setStatusPic("");

        // 获取商品状态图片 ignore
        if (isPic) {
            List<SystemGroupDataOrderStatusPicResponse> orderStatusPicList = systemGroupDataService.getListByGid(Constants.GROUP_DATA_ID_ORDER_STATUS_PIC, SystemGroupDataOrderStatusPicResponse.class);// 53 = group id 在groupData中查询数据

            for (SystemGroupDataOrderStatusPicResponse picList : orderStatusPicList) {
                if (null != orderAgainVoResult.getStatus()) {
                    if (picList.getOrderStatus() == orderAgainVoResult.getStatus().getType()) {
                        orderAgainVoResult.setStatusPic(picList.getUrl());
                        break;
                    }
                }
            }
        }
        String offlinePayStatus = systemConfigService.getValueByKey("offline_pay_status");
        int offlinePayStatusFlag = StringUtils.isNotBlank(offlinePayStatus) ? Integer.parseInt(offlinePayStatus) : 2;
        orderAgainVoResult.setOfflinePayStatus(offlinePayStatusFlag);
        return orderAgainVoResult;
    }

    /**
     * 缓存订单并做计算
     *
     * @param request
     */
    public ComputeOrderResponse computedOrder(OrderCreateRequest request, ConfirmOrderResponse cor, String orderKey) {
        ComputeOrderResponse result = new ComputeOrderResponse();
        if (request.getCouponId() != null && request.getCouponId() > 0 && BooleanUtils.isTrue(request.getUseIntegral())) {
            throw new CrmebException("不能同时使用优惠券和积分抵扣");
        }
        ChannelMerchant channelMerchant = channelMerchantService.getById(cor.getUserInfo().getMerId());
        if (request.getShippingType() == 2 && channelMerchant.getIsTake() == 0) {
            throw new CrmebException("该商户自提商品功能已关闭");
        }

        if (request.getShippingType() == 2) {
            // 校验当前商户是否允许自提商品
            boolean selfPickUp = checkSelfPickUpMer(cor.getUserInfo().getMerId());

            if (selfPickUp) {
                try {
                    // 检测是否是国内发货
                    boolean isCn = checkStockAreaCn(cor.getCartInfo());
                    // 商品是否是自建商品
                    boolean isSelfCreate = checkProductSelfCreate(cor.getCartInfo());
                    // 商品是否有拼团团长
                    boolean isHasLeader = checkProductLeader(request.getActivityGroupId());
                    log.info("isCn：{}，isSelfCreate：{}，isHasLeader：{}", isCn, isSelfCreate, isHasLeader);
                    if (isCn || isSelfCreate || isHasLeader) {
                        result.setIsAllowSelfPickUp(SwitchEnum.OPEN.getCode());
                    }else {
                        throw new CrmebException("只允许指定渠道商的自建商品及大陆现货或者指定团长的推广商品支持自提！");
                    }
                }catch (Exception e){
                    log.error("校验是否支持自提异常，", e);
                    throw new CrmebException("只允许指定渠道商的自建商品及大陆现货或者指定团长的推广商品支持自提！");
                }

            }else {
                log.error("当前商户不支持自提！");
            }
        }

        // 检查订单是否存在
        User currentUser = userService.getInfo();
        if (null == currentUser) {
            throw new CrmebException("用户不存在");
        }
        if (checkOrderExist(orderKey, currentUser.getUid())) {
            throw new CrmebException(orderKey + "订单已存在");
        }
        // 检测订单是否重复提交
        if (checkOrderSubmitAgain(orderKey)) {
            throw new CrmebException("请勿重复提交订单");
        }

        // 需要return的自定义变量
        BigDecimal couponPrice = BigDecimal.ZERO;
        BigDecimal deductionPrice = BigDecimal.ZERO;
        BigDecimal offDeductionPrice = BigDecimal.ZERO;
        Object rate = cor.getOther().get(Constants.CONFIG_KEY_INTEGRAL_RATE);
        BigDecimal integralRatio = rate == null ? BigDecimal.ZERO : new BigDecimal(rate.toString());
        Integer usedIntegral = 0;
        Integer gainIntegral = 0;//赠送积分
        Integer enoughIntegral = currentUser.getIntegral().multiply(integralRatio).intValue() > 0 ? 1 : 0;
        // TODO DIDIOK PRICE0
        BigDecimal totalPrice = cor.getPriceGroup().getTotalPrice();

        // 1
        int offliePayStatus = Integer.parseInt(systemConfigService.getValueByKey("offline_pay_status"));
        List<String> exsitPayType = getPayType().stream().filter(e -> offliePayStatus != 2).distinct().collect(Collectors.toList());
        if (exsitPayType.size() == 0) {
            throw new CrmebException("选择支付方式有误");
        }
        // 判断邮费是否正确
        BigDecimal payPostage = BigDecimal.ZERO;
        // 所有包邮的情况 线下付款包邮,
        // 1 线下支付和线下自提
        // 2 发货地是欧洲 - 收货地是香港, 发货地是内地-收货地是内地
        // 3 发货地是香港

        UserAddress currentUserAddress = new UserAddress();
        //快递还是自提
        if (request.getShippingType() == 1) {
            if (request.getAddressId() != null) {
                UserAddress ua = new UserAddress();
                ua.setUid(currentUser.getUid());
                ua.setId(request.getAddressId());
                currentUserAddress = userAddressService.getUserAddress(ua);
                cor.setAddressInfo(currentUserAddress);
            }
        } else {
            //自提
            takeShipAddress(request, cor, currentUserAddress);
        }
//        ua.setId(request.getAddressId());
//        // 还没有选择收货地址, 用默认收货地址算？ 如果选择到店自提,这个逻辑就不行了
//        UserAddress currentUserAddress = null;
//        if (request.getAddressId() != null) {
////            currentUserAddress = userAddressService.getDefault();
////        }else{
//            currentUserAddress = userAddressService.getUserAddress(ua);
//            cor.setAddressInfo(currentUserAddress);
//        }

        PriceGroupResponse currentOrderPriceGroup = priceUtil.getOrderPriceGroup(cor.getCartInfo(), currentUserAddress, cor.getUserInfo().getMerId());
        payPostage = currentOrderPriceGroup.getStorePostage();
        // TODO DIDIOK PRICE1
        BigDecimal payPrice = totalPrice.add(payPostage);
        // TODO 下面的要不要解开注释
        // 门店自提的逻辑先注释掉
//        if(request.getPayType().equals("offline") && systemConfigService.getValueByKey("offline_postage").equals("1")){
//            payPostage = BigDecimal.ZERO;
//        }else{
//            UserAddress ua = new UserAddress();
//            ua.setUid(currentUser.getUid());
//            ua.setId(request.getAddressId());
//            UserAddress currentUserAddress = userAddressService.getUserAddress(ua);
//            currentOrderPriceGroup = getOrderPriceGroup(cor.getCartInfo(), currentUserAddress);
//            payPostage = currentOrderPriceGroup.getStorePostage();
//        }
//        // 发快递还是门店自提
//        String storeSelfMention = systemConfigService.getValueByKey("store_self_mention");
//        int shippingType1 = 0;
//        if(Boolean.valueOf(storeSelfMention)) shippingType = 1;
//        if(Boolean.valueOf(storeSelfMention)){ // 是否包邮
//            if(StringUtils.isNotBlank(cor.getOther().get("offlinePostage").toString())
//                    && request.getPayType().equals(Constants.PAY_TYPE_OFFLINE)){
//                payPostage = BigDecimal.ZERO;
//            }
//            payPrice = payPrice.add(payPostage);
//        }else if(shippingType == 2){ // 门店自提没有邮费
//            cor.getPriceGroup().setStorePostage(BigDecimal.ZERO);
//            payPostage = BigDecimal.ZERO;
//        }
        // 检测优惠券
        int couponId = null != request.getCouponId() ? request.getCouponId() : 0;
        StoreCouponUserResponse storeCouponUserResponse = null;
        if (couponId > 0) {
            //取优惠券的信息,看是否需要判断 商品券或者品类券
            Boolean checkCoupon = storeCouponService.checkCoupon(couponId);
            if (!checkCoupon) {
                throw new CrmebException("优惠券异常");
            }
            StoreCouponUser storeCouponUser = storeCouponUserService.getById(couponId);
            boolean couponUseResult = storeCouponUserService.use(storeCouponUser, cor, channelMerchant, currentOrderPriceGroup);
            if (!couponUseResult) {
                throw new CrmebException("使用优惠券失败");
            }
            storeCouponUserResponse = new StoreCouponUserResponse();
            BeanUtils.copyProperties(storeCouponUser, storeCouponUserResponse);
            storeCouponUserResponse.setUseStartTime(storeCouponUser.getStartTime());
            storeCouponUserResponse.setUseEndTime(storeCouponUser.getEndTime());
            // 减去优惠券金额  后使用优惠券
            payPrice = payPrice.subtract(storeCouponUser.getMoney());
            couponPrice = storeCouponUser.getMoney();
        }

        int surPlusIntegral = currentUser.getIntegral().intValue();
        //使用积分抵扣金额
        BigDecimal useDeductionPrice = BigDecimal.ZERO;
        //开启积分抵扣
        int enableIntegral = Objects.equals(cor.getOther().get(Constants.CONFIG_KEY_INTEGRAL_ENABLE), true) ? 1 : 0;
        // 优惠套餐不适用积分
        if (Objects.nonNull(cor.getDiscountPackageId())) {
            enableIntegral = 0;
        }
        // 发货地是否是中国 不是大陆发货就是跨境商品，跨境商品不使用积分:大陆发货才使用积分

        if (enableIntegral == 1) {
            //积分使用需要过滤活动价格和跨境商品
            BigDecimal activityPrice = cor.getCartInfo().stream().filter(storeCartResponse -> (Objects.nonNull(storeCartResponse.getChannelActivity()) || !Objects.equals(storeCartResponse.getProductInfo().getTempId(), 1)))
                    .map(storeCartResponse -> storeCartResponse.getTruePrice().multiply(new BigDecimal(storeCartResponse.getCartNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
            //判断当前订单最多抵扣金额
            BigDecimal maxDeductionPrice = currentOrderPriceGroup.getTotalPrice().subtract(activityPrice).multiply(new BigDecimal(cor.getOther().get(Constants.CONFIG_KEY_INTEGRAL_PRICE_DEDUCTION_RATIO).toString()).movePointLeft(2)).setScale(2, RoundingMode.DOWN);
            //用户剩余积分最多抵扣金额
            BigDecimal maxIntegralPrice = currentUser.getIntegral().multiply(integralRatio).setScale(2, RoundingMode.DOWN);
            deductionPrice = maxDeductionPrice.compareTo(maxIntegralPrice) > 0 ? maxIntegralPrice : maxDeductionPrice;
            usedIntegral = deductionPrice.divide(integralRatio, 0, RoundingMode.UP).intValue();
            //抵扣积分
            if (BooleanUtils.isTrue(request.getUseIntegral())) {
                payPrice = payPrice.subtract(deductionPrice);
                useDeductionPrice = deductionPrice;
                surPlusIntegral = currentUser.getIntegral().intValue() - usedIntegral;
                List<Integer> integralProductIdList = cor.getCartInfo().stream().filter(e -> e.getChannelActivity() == null).map(StoreCartResponse::getProductId).distinct().collect(Collectors.toList());
                cor.setIntegralProductIdList(integralProductIdList);
            }
        }
        BigDecimal vipReducePrice = BigDecimal.ZERO;
        BigDecimal vipDiscountRatio = null;
        BigDecimal vipSubtotalAmount = null;
        //查询是否是会员
        UserMemberRecord member = userMemberRecordService.getUserMember(currentUser.getUid());
        if (member != null) {
            //查询会员抵扣折扣
            MerchantMemberBenefits memberBenefits = merchantMemberBenefitsService.getOne(Wrappers.<MerchantMemberBenefits>lambdaQuery().eq(MerchantMemberBenefits::getMerId, channelMerchant.getId())
                    .eq(MerchantMemberBenefits::getEquityType, 2)
                    .eq(MerchantMemberBenefits::getEquityEnableFlag, true)
                    .last("LIMIT 1"));
            if (memberBenefits != null && memberBenefits.getDiscountRatio() != null && memberBenefits.getDiscountConditions() != null) {
                //折扣条件 过滤活动商品
                Integer condition = memberBenefits.getDiscountConditions();
                List<Integer> productIdList = cor.getCartInfo().stream().filter(storeCartResponse -> Objects.isNull(storeCartResponse.getChannelActivity())).map(e -> e.getProductInfo().getId()).distinct().collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(productIdList)) {
                    BigDecimal activityTotalPrice = cor.getCartInfo().stream().filter(storeCartResponse -> Objects.nonNull(storeCartResponse.getChannelActivity()))
                            .map(storeCartResponse -> storeCartResponse.getTruePrice().multiply(new BigDecimal(storeCartResponse.getCartNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
                    BigDecimal activityPayPrice = cor.getCartInfo().stream().filter(storeCartResponse -> Objects.nonNull(storeCartResponse.getChannelActivity()))
                            .map(storeCartResponse -> (storeCartResponse.getTruePrice().add(storeCartResponse.getTaxAndSecondPrice())).multiply(new BigDecimal(storeCartResponse.getCartNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
                    currentOrderPriceGroup.setTotalPrice(currentOrderPriceGroup.getTotalPrice().subtract(activityTotalPrice));
                    currentOrderPriceGroup.setPayPrice(currentOrderPriceGroup.getPayPrice().subtract(activityPayPrice));
                    if (condition == 1) {
                        vipDiscountRatio = new BigDecimal(memberBenefits.getDiscountRatio().movePointLeft(2).stripTrailingZeros().toPlainString());
                        cor.setVipProductIdList(productIdList);
                        splitDeducePrice(cor, channelMerchant, couponPrice, useDeductionPrice);
                        //会员抵扣金额
                        getVipReducePrice(channelMerchant, memberBenefits, cor.getCartInfo(), productIdList);
                    } else if (condition == 2) {
                        //筛选会员商品
                        List<StoreProductDiscount> discountList = storeProductDiscountService.list(Wrappers.<StoreProductDiscount>lambdaQuery().eq(StoreProductDiscount::getMerId, channelMerchant.getId()).in(StoreProductDiscount::getProductId, productIdList));
                        if (CollectionUtils.isNotEmpty(discountList)) {
                            vipDiscountRatio = new BigDecimal(memberBenefits.getDiscountRatio().movePointLeft(2).stripTrailingZeros().toPlainString());
                            splitDeducePrice(cor, channelMerchant, couponPrice, useDeductionPrice);
                            //会员商品总价
                            List<Integer> vipProductIdList = discountList.stream().map(StoreProductDiscount::getProductId).distinct().collect(Collectors.toList());
                            cor.setVipProductIdList(vipProductIdList);
                            //会员抵扣金额
                            getVipReducePrice(channelMerchant, memberBenefits, cor.getCartInfo(), vipProductIdList);
                        }
                    }
                }
            }
        }
        //等级会员
        ChannelMemberLevel memberLevel = userService.getUserMemberLevel(currentUser);
        if (memberLevel != null) {
            if (memberLevel.getLevel() != 1) {
                splitDeducePrice(cor, channelMerchant, couponPrice, useDeductionPrice);
                switch (memberLevel.getPriceLadder()) {
                    case 2:
                        for (StoreCartResponse cartResponse : cor.getCartInfo()) {
                            List<BigDecimal> deductionPriceList = cartResponse.getDeductionPriceList();
                            if (cartResponse.getChannelActivity() == null) {
                                if (cartResponse.getLevelVipUpPrice() != null) {
                                    List<BigDecimal> levelVipReducePriceList = new ArrayList<>();
                                    for (int i = 0; i < cartResponse.getCartNum(); i++) {
                                        BigDecimal truePrice = cartResponse.getTruePrice().add(channelMerchant.getAppletType() == 1 ? cartResponse.getTaxAndSecondPrice() : BigDecimal.ZERO);
                                        BigDecimal reduceLevelPrice = truePrice.subtract(cartResponse.getLevelVipUpPrice());
                                        if (cartResponse.getLevelVipUpPrice().compareTo(deductionPriceList.get(i)) < 0) {
                                            reduceLevelPrice = truePrice.subtract(deductionPriceList.get(i));
                                        }
                                        levelVipReducePriceList.add(reduceLevelPrice);
                                    }
                                    cartResponse.setLevelVipReducePriceList(levelVipReducePriceList);
                                }
                            }
                        }
                        break;
                    case 3:
                        for (StoreCartResponse cartResponse : cor.getCartInfo()) {
                            if (cartResponse.getChannelActivity() == null) {
                                List<BigDecimal> deductionPriceList = cartResponse.getDeductionPriceList();
                                List<BigDecimal> levelVipReducePriceList = new ArrayList<>();
                                for (int i = 0; i < cartResponse.getCartNum(); i++) {
                                    BigDecimal levelVipPrice = cartResponse.getTruePrice().subtract(deductionPriceList.get(i)).add(channelMerchant.getAppletType() == 1 ? cartResponse.getTaxAndSecondPrice() : BigDecimal.ZERO);
                                    BigDecimal reduceLevelPrice = levelVipPrice.multiply(BigDecimal.ONE.subtract(memberLevel.getRatio().movePointLeft(2))).setScale(2, RoundingMode.DOWN);
                                    levelVipReducePriceList.add(reduceLevelPrice);
                                }
                                cartResponse.setLevelVipReducePriceList(levelVipReducePriceList);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        //满减送计算
        Map<String, Object> discountMap = priceUtil.getDiscountPrice(cor.getCartInfo(), cor.getUserInfo().getMerId(), Objects.isNull(cor.getAddressInfo()) ? 0 : cor.getAddressInfo().getAreaType());
        BigDecimal discountPrice = (BigDecimal) discountMap.get("discountPrice");
        payPrice = payPrice.subtract(discountPrice);
        //累加最优优惠
        List<VipDiscountVo> vipDiscountList = new ArrayList<>();
        for (StoreCartResponse cartResponse : cor.getCartInfo()) {
            cartResponse.setAppletType(channelMerchant.getAppletType());
            List<BigDecimal> vipReducePriceList = cartResponse.getVipReducePriceList();
            List<BigDecimal> levelVipReducePriceList = cartResponse.getLevelVipReducePriceList();
            BigDecimal price1 = vipReducePriceList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal price2 = levelVipReducePriceList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
            if (price1.compareTo(price2) > -1 && price1.compareTo(BigDecimal.ZERO) > 0) {
                vipReducePrice = vipReducePrice.add(price1);
                vipDiscountList.add(new VipDiscountVo(cartResponse.getProductId(), cartResponse.getProductInfo().getAttrInfo().getSourceSkuId(), 0, cartResponse.getCartNum(), price1));
            } else if (price2.compareTo(price1) > 0 && price2.compareTo(BigDecimal.ZERO) > 0) {
                vipReducePrice = vipReducePrice.add(price2);
                vipDiscountList.add(new VipDiscountVo(cartResponse.getProductId(), cartResponse.getProductInfo().getAttrInfo().getSourceSkuId(), 1, cartResponse.getCartNum(), price2));
            }
        }
        if (BooleanUtils.isTrue(request.getUseMember())) {
            payPrice = payPrice.subtract(vipReducePrice);
        }

//        HashMap<String, Object> resultMap = new HashMap<>();
        // 是否生成订单
//        if(isCreateOrder){
        // todo 秒杀在这里需要判断库存

//        StoreOrder orderCreated = createOrder(request, cor, 0, request.getStoreId());
//        resultMap.put("orderCreate", orderCreated);
//        }
        // 优惠套餐价格计算
        if (Objects.nonNull(cor.getDiscountPackageId())) {
            payPrice = channelDiscountPackageService.getPayPrice(cor.getDiscountPackageId(), cor.getCartInfo());
        }
        payPrice = payPrice.add(currentOrderPriceGroup.getTaxPrice());
        // 组装返回数据
        result.setTotalPrice(cor.getPriceGroup().getTotalPrice());
        result.setPackagePrice(cor.getPriceGroup().getPackagePrice());
        // TODO DIDIOK PRICE3
        result.setPayPrice(payPrice.setScale(2, BigDecimal.ROUND_CEILING));
        //TODO 好像漏加了税费
        payPostage = payPostage.add(currentOrderPriceGroup.getTaxPrice());
        result.setPayPostage(payPostage.setScale(2, BigDecimal.ROUND_CEILING));
        result.setCouponPrice(couponPrice.setScale(2, RoundingMode.CEILING));
        result.setDeductionPrice(deductionPrice.setScale(2, BigDecimal.ROUND_CEILING));
        result.setVipReducePrice(vipReducePrice);
        result.setDiscountInfo(discountMap);
        if (null != vipDiscountRatio) {
            result.setVipDiscountRatio(vipDiscountRatio.movePointRight(1));
        }
        result.setVipProductIdList(cor.getVipProductIdList());
//        result.setVipSubtotalAmount(vipSubtotalAmount);
        result.setUsedIntegral(usedIntegral);
        result.setGainIntegral(gainIntegral);
        result.setEnoughIntegral(enoughIntegral);
        // 是否使用积分支付
        result.setEnableIntegral(enableIntegral);
        result.setSurplusIntegral(surPlusIntegral);
        result.setArrivalTime(currentOrderPriceGroup.getArrivalTime());
        result.setCostPrice(currentOrderPriceGroup.getCostPrice());
        result.setSourceCostPrice(currentOrderPriceGroup.getSourceCostPrice());
        result.setVipDiscountList(vipDiscountList);
        result.setMemberLevel(memberLevel);
        // 更新计算后的数据到订单缓存
        cor.getPriceGroup().setTotalPrice(result.getTotalPrice());
        cor.getPriceGroup().setPackagePrice(result.getPackagePrice());
        // TODO DIDIOK PRICE4
        cor.getPriceGroup().setPayPrice(result.getPayPrice());
        cor.getPriceGroup().setPayPostage(result.getPayPostage());
        cor.getPriceGroup().setCouponPrice(result.getCouponPrice());
        cor.getPriceGroup().setVipReducePrice(BooleanUtils.isTrue(request.getUseMember()) ? vipReducePrice : BigDecimal.ZERO);
        cor.getPriceGroup().setVipDiscountRatio(vipDiscountRatio);
        cor.getPriceGroup().setDeductionPrice(request.getUseIntegral() ? deductionPrice.setScale(2, BigDecimal.ROUND_CEILING) : BigDecimal.ZERO);
        cor.getPriceGroup().setUsedIntegral(request.getUseIntegral() ? result.getUsedIntegral() : 0);
        cor.getPriceGroup().setGainIntegral(result.getGainIntegral());
        cor.getPriceGroup().setEnableIntegral(result.getEnableIntegral());
        cor.getPriceGroup().setArrivalTime(currentOrderPriceGroup.getArrivalTime());
        cor.getPriceGroup().setCostPrice(result.getCostPrice());
        cor.getPriceGroup().setSourceCostPrice(result.getSourceCostPrice());
        cor.setUsableCoupon(storeCouponUserResponse);
        cor.setUseIntegral(request.getUseIntegral());
        cor.setShippingType(request.getShippingType());
        cor.setMemberLevel(memberLevel);
        cor.setVipDiscountList(vipDiscountList);
        cor.setDiscountInfo(discountMap);
//        cacheDeleteOrderInfo(currentUser.getUid(), orderKey);
        cacheRepliceOrderInfo(orderKey, currentUser.getUid(), cor);
        return result;
    }

    public boolean checkAllowSelfPickUp(Integer merId, Integer productId, String groupId) {
        // 校验当前商户是否允许自提商品
        boolean selfPickUp = checkSelfPickUpMer(merId);
        if (selfPickUp) {
            // 商品是否有拼团团长(有团就有团长，团是根据团长查出来的)
            if(StringUtils.isNotBlank(groupId) && !"0".equals(groupId)){
                return true;
            }
            // 检测是否是国内发货,是否是自建商品
            StoreProduct product = storeProductService.getById(productId);
            if(Objects.equals(product.getTempId(), 1) || ProductTypeEnum.INSIDE.getCode().equals(product.getIsEurope())){
                return true;
            }

        }
        return false;
    }

    public boolean checkAllowSelfPickUpList(Integer merId, List<Integer> productIdList, String groupId) {
        // 校验当前商户是否允许自提商品
        boolean selfPickUp = checkSelfPickUpMer(merId);
        if (selfPickUp) {
            // 商品是否有拼团团长(有团就有团长，团是根据团长查出来的)
            if(StringUtils.isNotBlank(groupId) && !"0".equals(groupId)){
                return true;
            }
            // 检测是否是国内发货,是否是自建商品
            List<StoreProduct> storeProductList = storeProductService.list(Wrappers.lambdaQuery(StoreProduct.class).in(StoreProduct::getId, productIdList));
            for(StoreProduct product : storeProductList){
                if(!Objects.equals(product.getTempId(), 1) && !ProductTypeEnum.INSIDE.getCode().equals(product.getIsEurope())){
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * 商品是否有拼团团长
     * @return
     */
    private boolean checkProductLeader(Integer activityGroupId) {
        if(null == activityGroupId || 0 == activityGroupId){
            return false;
        }
        ChannelGroupBooking channelGroupBooking = channelGroupBookingService.getById(activityGroupId);
        Integer leaderId = channelGroupBooking.getLeaderId();
        if(null == leaderId || 0 == leaderId){
            return false;
        }
        return true;
    }

    /**
     * 商品是否是自建商品，是否是拼团商品
     * @param cartInfo
     * @return
     */
    private boolean checkProductSelfCreate(List<StoreCartResponse> cartInfo) {
        //商品id
        List<Integer> idList = cartInfo.stream().map(StoreCartResponse::getProductId).collect(Collectors.toList());
        List<StoreProduct> storeProductList = storeProductService.list(Wrappers.lambdaQuery(StoreProduct.class).in(StoreProduct::getId, idList));
        for(StoreProduct product : storeProductList){
            if(!ProductTypeEnum.INSIDE.getCode().equals(product.getIsEurope())){
                return false;
            }
        }
        return true;
    }

    /**
     * 检测是否是国内发货
     * @param cartInfo
     */
    private boolean checkStockAreaCn(List<StoreCartResponse> cartInfo) {
        //跨境商品
        List<StoreCartResponse> list = cartInfo.stream().filter(storeCartResponse -> !Objects.equals(storeCartResponse.getProductInfo().getTempId(), 1)).collect(Collectors.toList());
        if(list.size() > 0){
            return false;
        }
        return true;
    }

    /**
     * 校验当前商户是否允许自提商品
     * @param merIdInt
     * @return
     */
    private boolean checkSelfPickUpMer(Integer merId) {
        List<Integer> pickUpMerIds = CrmebUtil.jsonToListInteger(Constants.SELF_PICKUP_MERCHANT);
        if(pickUpMerIds.contains(merId)){
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        List<Integer> pickUpMerIds = CrmebUtil.jsonToListInteger(Constants.SELF_PICKUP_MERCHANT);
        for(Integer id : pickUpMerIds){
            System.out.println(id);
        }

    }
    public ComputeOrderResponse computedPickingOrder(OrderCreateRequest request, ConfirmOrderResponse cor, String orderKey) {
        ChannelMerchant channelMerchant = channelMerchantService.getById(cor.getUserInfo().getMerId());
        if (request.getShippingType() == 2 && channelMerchant.getIsTake() == 0) {
            throw new CrmebException("该商户自提商品功能已关闭");
        }
        // 检查订单是否存在
        User currentUser = userService.getInfo();
        if (null == currentUser) {
            throw new CrmebException("用户不存在");
        }
        if (checkOrderExist(orderKey, currentUser.getUid())) {
            throw new CrmebException(orderKey + "订单已存在");
        }
        // 检测订单是否重复提交
        if (checkOrderSubmitAgain(orderKey)) {
            throw new CrmebException("请勿重复提交订单");
        }
        // 需要return的自定义变量
        BigDecimal totalPrice = cor.getPriceGroup().getTotalPrice();
        // 1
        int offliePayStatus = Integer.parseInt(systemConfigService.getValueByKey("offline_pay_status"));
        List<String> exsitPayType = getPayType().stream().filter(e -> offliePayStatus != 2).distinct().collect(Collectors.toList());
        if (exsitPayType.size() == 0) {
            throw new CrmebException("选择支付方式有误");
        }
        // 判断邮费是否正确
        BigDecimal payPostage = BigDecimal.ZERO;
        // 所有包邮的情况 线下付款包邮,
        UserAddress currentUserAddress = new UserAddress();
        //快递还是自提
        if (request.getShippingType() == 1) {
            if (request.getAddressId() != null) {
                UserAddress ua = new UserAddress();
                ua.setUid(currentUser.getUid());
                ua.setId(request.getAddressId());
                currentUserAddress = userAddressService.getUserAddress(ua);
                cor.setAddressInfo(currentUserAddress);
            }
        } else {
            //自提
            takeShipAddress(request, cor, currentUserAddress);
        }
        PriceGroupResponse currentOrderPriceGroup = priceUtil.getOrderPriceGroup(cor.getCartInfo(), currentUserAddress, cor.getUserInfo().getMerId());
        if (currentUserAddress != null) {
            if (!Objects.equals(cor.getPriceGroup().getAreaType(), currentUserAddress.getAreaType())) {
                throw new CrmebException("收货地址与批采单收货类型不匹配");
            }
        }
        payPostage = currentOrderPriceGroup.getStorePostage();
        BigDecimal payPrice = totalPrice.add(payPostage);
        ChannelPicking channelPicking = channelPickingService.getById(currentOrderPriceGroup.getPickingId());
        if (channelPicking.getIsDel() == 1) {
            throw new CrmebException("该批采单已被删除");
        }
        if (channelPicking.getStatementTime().before(new Date())) {
            throw new CrmebException("该批采单已过结单时间");
        }
        if (channelPicking.getMinimumPrice().compareTo(payPrice) > 0) {
            throw new CrmebException("未达到起订金额");
        }
        cor.getCartInfo().forEach(e -> e.setAppletType(channelMerchant.getAppletType()));
        ComputeOrderResponse result = new ComputeOrderResponse();
        // 组装返回数据
        result.setTotalPrice(cor.getPriceGroup().getTotalPrice());
        result.setPayPrice(payPrice);
        result.setPayPostage(payPostage);
        result.setCouponPrice(BigDecimal.ZERO);
        result.setDeductionPrice(BigDecimal.ZERO);
        result.setVipReducePrice(BigDecimal.ZERO);
        result.setVipDiscountRatio(BigDecimal.ZERO);
        result.setVipProductIdList(cor.getVipProductIdList());
        result.setVipSubtotalAmount(BigDecimal.ZERO);
        result.setUsedIntegral(0);
        result.setGainIntegral(0);
        result.setEnoughIntegral(0);
        result.setEnableIntegral(0);
        result.setSurplusIntegral(0);
        result.setArrivalTime(currentOrderPriceGroup.getArrivalTime());
        result.setCostPrice(currentOrderPriceGroup.getCostPrice());
        result.setSourceCostPrice(currentOrderPriceGroup.getSourceCostPrice());
        // 更新计算后的数据到订单缓存
        cor.getPriceGroup().setTotalPrice(result.getTotalPrice());
        cor.getPriceGroup().setPayPrice(result.getPayPrice());
        cor.getPriceGroup().setPayPostage(result.getPayPostage());
        cor.getPriceGroup().setCouponPrice(result.getCouponPrice());
        cor.getPriceGroup().setVipReducePrice(BigDecimal.ZERO);
        cor.getPriceGroup().setVipDiscountRatio(BigDecimal.ZERO);
        cor.getPriceGroup().setDeductionPrice(BigDecimal.ZERO);
        cor.getPriceGroup().setUsedIntegral(request.getUseIntegral() ? result.getUsedIntegral() : 0);
        cor.getPriceGroup().setGainIntegral(result.getGainIntegral());
        cor.getPriceGroup().setEnableIntegral(result.getEnableIntegral());
        cor.getPriceGroup().setArrivalTime(currentOrderPriceGroup.getArrivalTime());
        cor.getPriceGroup().setCostPrice(result.getCostPrice());
        cor.getPriceGroup().setSourceCostPrice(result.getSourceCostPrice());
        cor.getPriceGroup().setPickingId(currentOrderPriceGroup.getPickingId());
        cor.setUsableCoupon(null);
        cor.setUseIntegral(request.getUseIntegral());
        cor.setShippingType(request.getShippingType());
//        cacheDeleteOrderInfo(currentUser.getUid(), orderKey);
        cacheRepliceOrderInfo(orderKey, currentUser.getUid(), cor);
        return result;
    }

    private void getVipReducePrice(ChannelMerchant channelMerchant, MerchantMemberBenefits memberBenefits, List<StoreCartResponse> cartInfo, List<Integer> vipProductIdList) {
        for (StoreCartResponse cartResponse : cartInfo) {
            if (vipProductIdList.contains(cartResponse.getProductId())) {
                List<BigDecimal> vipReducePriceList = new ArrayList<>();
                for (int i = 0; i < cartResponse.getCartNum(); i++) {
                    List<BigDecimal> deductionPriceList = cartResponse.getDeductionPriceList();
                    BigDecimal vipPrice = cartResponse.getTruePrice().subtract(deductionPriceList.get(i)).add(channelMerchant.getAppletType() == 1 ? cartResponse.getTaxAndSecondPrice() : BigDecimal.ZERO);
                    BigDecimal vipReducePrice = vipPrice.multiply(BigDecimal.ONE.subtract(memberBenefits.getDiscountRatio().movePointLeft(2))).setScale(2, RoundingMode.DOWN);
                    vipReducePriceList.add(vipReducePrice);
                }
                cartResponse.setVipReducePriceList(vipReducePriceList);
            }
        }
    }

    private void splitDeducePrice(ConfirmOrderResponse cor, ChannelMerchant channelMerchant, BigDecimal couponPrice, BigDecimal useDeductionPrice) {
        List<StoreCartResponse> sortList = cor.getCartInfo().stream().sorted(Comparator.comparing(StoreCartResponse::getTruePrice).reversed()).collect(Collectors.toList());
        CalculatePriceVo calculateVo = new CalculatePriceVo();
        if (couponPrice.compareTo(BigDecimal.ZERO) > 0) {
            calculateVo = getCalculate(cor, null, couponPrice, cor.getProductIdList(), false);
        } else if (useDeductionPrice.compareTo(BigDecimal.ZERO) > 0) {
            calculateVo = getCalculate(cor, null, useDeductionPrice, cor.getIntegralProductIdList(), false);
        }
        //已抵扣金额
        for (StoreCartResponse cartResponse : sortList) {
            boolean isCoupon = getFlag(cartResponse, cor.getProductIdList());
            boolean isIntegral = getFlag(cartResponse, cor.getIntegralProductIdList());
            List<BigDecimal> deductionPriceList = new ArrayList<>();
            for (int i = 0; i < cartResponse.getCartNum(); i++) {
                calculateVo.setReducePrice(BigDecimal.ZERO);
                //优惠券拆分
                getReducePrice(channelMerchant, calculateVo, cartResponse, isCoupon, couponPrice, true, BigDecimal.ZERO);
                //商品抵扣金额
                getReducePrice(channelMerchant, calculateVo, cartResponse, isIntegral, useDeductionPrice, false, BigDecimal.ZERO);
                deductionPriceList.add(calculateVo.getReducePrice());
            }
            cartResponse.setDeductionPriceList(deductionPriceList);
        }
    }

    /**
     * 创建订单
     *
     * @param request   订单创建参数
     * @param cor       缓存的购物车，价钱等信息集合
     * @param isChannel 购买渠道
     * @param orderId   订单id
     * @return 订单信息
     */
    @Transactional(rollbackFor = {RuntimeException.class, Error.class, CrmebException.class})
    public StoreOrder createOrder(OrderCreateRequest request, ConfirmOrderResponse cor, Integer isChannel, Integer orderId, String orderKey) {
        Integer totalNum = cor.getCartInfo().stream().mapToInt(StoreCartResponse::getCartNum).sum();
        StoreOrder storeOrder = new StoreOrder();
        User currentUser = userService.getInfo();

        if(StringUtils.isBlank(cor.getAddressInfo().getIdName()) && StringUtils.isNotBlank(request.getIdName())){
            cor.getAddressInfo().setIdName(request.getIdName());
        }
        if(StringUtils.isBlank(cor.getAddressInfo().getIdCard()) && StringUtils.isNotBlank(request.getIdCard())){
            cor.getAddressInfo().setIdCard(request.getIdCard());
        }
        if(StringUtils.isBlank(cor.getAddressInfo().getSeatNo()) && StringUtils.isNotBlank(request.getSeatNo())){
            cor.getAddressInfo().setSeatNo(request.getSeatNo());
        }

        //判断参数和缓存中订单
        checkCreateOrderRequest(request, cor);
        //1.收货信息
        shipAddress(request, cor);
        // 校验个人年度金额
        StoreProduct storeProduct = getRandomProductInfo(cor);
        // 商品发货地不是中国的校验年度个人额度
        if (null != storeProduct && !Objects.equals(storeProduct.getTempId(),StockAreaTempEnum.CN.getTempId())){
            CommonResult<String> checkResult = personPayLimitUtils.checkPrice(cor.getPriceGroup().getPayPrice(), request.getIdCard(), request.getIdName());
            DingTalkMsgUtil.sendMsg(DingMsgEnum.ORDER_PAY,request.getIdCard()+","+request.getIdName()+",result:"+checkResult.getMessage());
            if (!Objects.equals(checkResult.getCode(), ExceptionCodeEnum.SUCCESS.getCode())){
                throw new CrmebException(checkResult.getMessage());
            }
        }

        //2.生成主订单
        addStoreOrder(request, cor, currentUser, storeOrder, totalNum, isChannel, orderKey);

        //当前订单抵扣积分
        //gainIntegral = cor.getPriceGroup().getPayPrice().multiply(BigDecimal.valueOf(Integer.valueOf(systemConfigService.getValueByKey("order_give_integral")))).intValue();
        //3.创建订单积分扣减
        storeOrderService.updateUserIntegral(storeOrder, currentUser);
        //4.主订单明细
        if (storeOrder.getPickingId() > 0) {
            //批采
            addPickingOrderInfo(cor, storeOrder, request.getMerId());
        } else {
            //5.生成子订单
            addOrderInfo(cor, storeOrder, request.getMerId());
        }

        //校验地址
        checkAddr(request.getMerId(), cor);

        //6.删除购物车
        deleteCartInfo(cor, currentUser, storeOrder, orderKey);

        // 设置订单id
        request.setOrderAutoId(storeOrder.getId());
        return storeOrder;
    }

    private StoreProduct getRandomProductInfo(ConfirmOrderResponse cor) {
        if (null == cor || CollectionUtils.isEmpty(cor.getCartInfo())){
            return null;
        }
        StoreCartResponse storeCartResponse = cor.getCartInfo().get(0);
        if ( null == storeCartResponse || null == storeCartResponse.getProductInfo()){
            return null;
        }
        StoreProduct storeProduct = storeProductService.getById(storeCartResponse.getProductId());
        return storeProduct;
    }

    private void checkCreateOrderRequest(OrderCreateRequest request, ConfirmOrderResponse cor) {
        if (request.getAddressId() == null) {
            throw new CrmebException("请选择收货地址");
        }
        if (Objects.isNull(cor.getAddressInfo()) || !Objects.equals(request.getAddressId(), cor.getAddressInfo().getId())) {
            throw new CrmebException("收货地址异常,请重新下单");
        }
        if (!Objects.equals(request.getCouponId(), null == cor.getUsableCoupon() ? 0 : cor.getUsableCoupon().getId())) {
            throw new CrmebException("使用优惠卷异常,请重新下单");
        }
        if (!Objects.equals(request.getUseIntegral(), cor.getUseIntegral())) {
            throw new CrmebException("使用积分异常,请重新下单");
        }
        if (!Objects.equals(request.getShippingType(), cor.getShippingType())) {
            throw new CrmebException("快递类型异常,请重新下单");
        }
    }

    /**
     * 校验地址
     * 如果发货地为海外，则收货地址身份证必填
     *
     * @param cor
     */
    private void checkAddr(Integer merId, ConfirmOrderResponse cor) {
        //自提跳过
        if (cor.getAddressInfo().getUid() == null) {
            return;
        }
        if (!checkIdCard) {
            return;
        }
        ChannelMerchant channelMerchant = channelMerchantService.getById(merId);
        if (channelMerchant.getChannelType() == 8) {
            return;
        }
        cor.getCartInfo().forEach(e -> {
            if (!Objects.equals(e.getProductInfo().getTempId(), 1) && cor.getAddressInfo().getAreaType() == 1 && StringUtils.isBlank(cor.getAddressInfo().getIdCard())) {
                throw new CrmebException("非大陆地区发货且大陆收货的情况下需要填写身份证");
            }
        });
    }

    /**
     * 组装订单数据
     */
    private Object assembleStoreOrderParam(Object obj, OrderCreateRequest request, ConfirmOrderResponse cor, User currentUser, Integer totalNum, Integer gainIntegral, Integer isChannel, String orderKey) {

        //用户id
        invoke(obj, "uid", cor.getUserInfo().getUid());

        //订单编号
        invoke(obj, "orderId", CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT));

        // 后置选择收货地址信息
        if (null == cor.getAddressInfo() && request.getAddressId() > 0) {
            UserAddress selectUserAddress = userAddressService.getById(request.getAddressId());
            cor.setAddressInfo(selectUserAddress);
        }

        //真实名称
        invoke(obj, "realName", cor.getAddressInfo().getRealName());
        //收货手机号
        invoke(obj, "userPhone", cor.getAddressInfo().getPhone());
        //收货地址
        String userAddress = cor.getAddressInfo().getProvince()
                + cor.getAddressInfo().getCity()
                + cor.getAddressInfo().getDistrict()
                + cor.getAddressInfo().getDetail();
        invoke(obj, "userAddress", userAddress);

//        storeOrder.setCarId(cartIds);
        //商品总数量
        invoke(obj, "totalNum", totalNum);

        BigDecimal mapTotalPrice = cor.getPriceGroup().getTotalPrice();
        BigDecimal mapStorePostage = cor.getPriceGroup().getStorePostage();
        BigDecimal mapCouponPrice = cor.getPriceGroup().getCouponPrice();
        BigDecimal mapPayPrice = cor.getPriceGroup().getPayPrice();
        BigDecimal mapPayPostage = cor.getPriceGroup().getPayPostage();
        BigDecimal mapDeductionPrice = cor.getPriceGroup().getDeductionPrice();
        Integer mapUsedIntegral = cor.getPriceGroup().getUsedIntegral();
        BigDecimal mapCostPrice = cor.getPriceGroup().getCostPrice();
        BigDecimal mapSourceCostPrice = cor.getPriceGroup().getSourceCostPrice();

        int couponId = null == cor.getUsableCoupon() ? 0 : cor.getUsableCoupon().getId();

        //订单总金额
        invoke(obj, "totalPrice", mapTotalPrice);

        //运费
        invoke(obj, "totalPostage", mapStorePostage);

        //优惠券id
        invoke(obj, "couponId", couponId);

        //优惠金额
        invoke(obj, "couponPrice", mapCouponPrice);

        //支付金额
        invoke(obj, "payPrice", mapPayPrice);

        //
        invoke(obj, "payPostage", mapPayPostage);

        //
        invoke(obj, "deductionPrice", mapDeductionPrice);

//        storeOrder.setPaid(false);

        invoke(obj, "payType", request.getPayType());

        invoke(obj, "useIntegral", mapUsedIntegral);

        invoke(obj, "gainIntegral", gainIntegral);

        invoke(obj, "mark", StringEscapeUtils.escapeHtml4(request.getMark()));

        invoke(obj, "combinationId", request.getCombinationId());

        invoke(obj, "pinkId", request.getPinkId());

        invoke(obj, "seckillId", request.getSeckillId());

        invoke(obj, "bargainId", request.getBargainId());

        invoke(obj, "cost", mapCostPrice);

        invoke(obj, "sourceCost", mapSourceCostPrice);

        invoke(obj, "isChannel", isChannel);

        invoke(obj, "createTime", DateUtil.nowDateTime());

        invoke(obj, "unique", orderKey);

        invoke(obj, "shippingType", request.getShippingType());

        // 如果是自提
        if (request.getShippingType() == 2) {
            invoke(obj, "verifyCode", CrmebUtil.randomCount(1111111111, 999999999) + "");
            SystemStore systemStore = new SystemStore();
            systemStore.setId(request.getStoreId());
            systemStore.setIsShow(true);
            systemStore.setIsDel(false);
            SystemStore existSystemStore = systemStoreService.getByCondition(systemStore);
            if (null == existSystemStore) {
                throw new CrmebException("暂无门店无法选择门店自提");
            }
            invoke(obj, "storeId", existSystemStore.getId());
        }


        if (ObjectUtil.isNotEmpty(currentUser)) {
            invoke(obj, "createName", currentUser.getNickname());
        }

        return obj;
    }


    /**
     * 用反射设置对象的属性值
     *
     * @param obj   需要設置值的對象
     * @param value 需要设置的值
     * @return 设置值后的对象
     */
    private Object invoke(Object obj, String methodName, Object value) {

        try {
            Method method = obj.getClass().getMethod(methodName, value.getClass());
            method.invoke(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return obj;
    }

    /**
     * 创建订单 - 收货信息
     *
     * @param request
     * @param cor
     */
    private void shipAddress(OrderCreateRequest request, ConfirmOrderResponse cor) {
        List<Integer> cartIds = new ArrayList<>();

        // todo 开启事务
        if (request.getShippingType() == 1) { // 是否包邮
            UserAddress userAddress = new UserAddress();
            userAddress.setId(request.getAddressId());
            userAddress.setIsDel(false);
            if (null == userAddressService.getUserAddress(userAddress)) {
                throw new CrmebException("收货地址有误");
            }
        } else {
            //自提
            MerchantAddress merchantAddress = merchantAddressService.getById(request.getAddressId());
            if (merchantAddress == null || merchantAddress.getStatus() == 0) {
                throw new CrmebException("自提收货地址有误");
            }
        }
//        else {
//            // 到店自提
//            if (StringUtils.isBlank(cor.getAddressInfo().getRealName()) || StringUtils.isBlank(cor.getAddressInfo().getRealName())) {
//                throw new CrmebException("请填写姓名和电话");
//            }
//
//            currentUserAddress.setRealName(cor.getAddressInfo().getRealName());
//            currentUserAddress.setPhone(cor.getAddressInfo().getRealName());
//        }

        for (StoreCartResponse cartResponse : cor.getCartInfo()) {
            cartIds.add(cartResponse.getSeckillId());
            //totalNum += cartResponse.getCartNum();
            // todo 秒杀拼团砍价 二期
            /*Integer cartInfoGainIntegral =
                    (cartResponse.getProductInfo().getGiveIntegral() != null && cartResponse.getProductInfo().getGiveIntegral() > 0) ?
                            cartResponse.getProductInfo().getGiveIntegral() * cartResponse.getCartNum()
                            : 0;*/
            //gainIntegral = gainIntegral + cartInfoGainIntegral;
        }
        // todo 检测营销产品状态
        // 发快递还是门店自提
//        String storeSelfMention = systemConfigService.getValueByKey("store_self_mention");
//        if (Boolean.valueOf(storeSelfMention)) request.setShippingType(1);
    }

    private void takeShipAddress(OrderCreateRequest request, ConfirmOrderResponse cor, UserAddress currentUserAddress) {
        if (request.getAddressId() == null) {
            throw new CrmebException("自提收货地址id不能为空");
        }
        MerchantAddress merchantAddress = merchantAddressService.getById(request.getAddressId());
        if (merchantAddress == null || merchantAddress.getStatus() == 0) {
            throw new CrmebException("收货地址有误");
        }
        BeanUtils.copyProperties(merchantAddress, currentUserAddress);
        cor.setAddressInfo(currentUserAddress);
    }

    /**
     * 创建订单 - 生成主订单
     *
     * @param request
     * @param cor
     * @param currentUser
     * @param storeOrder
     * @param totalNum
     * @param isChannel
     * @param orderKey
     */
    private void addStoreOrder(OrderCreateRequest request, ConfirmOrderResponse cor, User currentUser, StoreOrder storeOrder, Integer totalNum, Integer isChannel, String orderKey) {

        storeOrder.setMerId(request.getMerId());
        storeOrder.setUid(cor.getUserInfo().getUid());
        storeOrder.setOrderId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT));

        // 后置选择收货地址信息
        if (null == cor.getAddressInfo() && request.getAddressId() > 0) {
            UserAddress selectUserAddress = userAddressService.getById(request.getAddressId());
            cor.setAddressInfo(selectUserAddress);
        }

        storeOrder.setIdCard(cor.getAddressInfo().getIdCard());
        storeOrder.setRealName(cor.getAddressInfo().getRealName());
        storeOrder.setUserPhone(cor.getAddressInfo().getPhone());
        storeOrder.setAreaType(cor.getAddressInfo().getAreaType());
        if(SwitchEnum.OPEN.getCode().equals(request.getIsAllowSelfPickUp())){
            cor.getAddressInfo().setDetail(cor.getAddressInfo().getDetail() + "，座位号：" + cor.getAddressInfo().getSeatNo());
        }
        storeOrder.setUserAddress(cor.getAddressInfo().getProvince()
                + cor.getAddressInfo().getCity()
                + cor.getAddressInfo().getDistrict()
                + cor.getAddressInfo().getDetail());

        storeOrder.setProvince(cor.getAddressInfo().getProvince());
        storeOrder.setCity(cor.getAddressInfo().getCity());
        storeOrder.setDistrict(cor.getAddressInfo().getDistrict());
        storeOrder.setDetail(cor.getAddressInfo().getDetail());
//        storeOrder.setCarId(cartIds);
        storeOrder.setTotalNum(totalNum);
        BigDecimal mapTotalPrice = cor.getPriceGroup().getTotalPrice();
        BigDecimal mapPackagePrice = cor.getPriceGroup().getTotalPrice();
        BigDecimal mapStorePostage = cor.getPriceGroup().getStorePostage();
        BigDecimal mapCouponPrice = cor.getPriceGroup().getCouponPrice();
        // TODO DIDIOK PRICE5
        BigDecimal mapPayPrice = cor.getPriceGroup().getPayPrice();
        BigDecimal mapPayPostage = cor.getPriceGroup().getPayPostage();
        BigDecimal mapDeductionPrice = cor.getPriceGroup().getDeductionPrice();
        Integer mapUsedIntegral = cor.getPriceGroup().getUsedIntegral();
        Integer gainIntegral = cor.getPriceGroup().getGainIntegral();
        Integer enableIntegral = cor.getPriceGroup().getEnableIntegral();
        BigDecimal mapCostPrice = cor.getPriceGroup().getCostPrice();
        BigDecimal mapSourceCostPrice = cor.getPriceGroup().getSourceCostPrice();

        int couponId = null == cor.getUsableCoupon() ? 0 : cor.getUsableCoupon().getId();
        storeOrder.setTotalPrice(mapTotalPrice);
        storeOrder.setPackagePrice(mapPackagePrice);
        storeOrder.setTotalPostage(mapStorePostage);
        storeOrder.setCouponId(couponId);
        storeOrder.setCouponPrice(mapCouponPrice);
        // TODO DIDIOK PRICE6
        storeOrder.setPayPrice(mapPayPrice);
        storeOrder.setPayPostage(mapPayPostage);
        storeOrder.setDeductionPrice(mapDeductionPrice);
        storeOrder.setVipReducePrice(cor.getPriceGroup().getVipReducePrice());
//        storeOrder.setPaid(false);
        storeOrder.setPayType(request.getPayType());
        storeOrder.setUseIntegral(mapUsedIntegral);
        storeOrder.setGainIntegral(gainIntegral);
        storeOrder.setEnableIntegral(enableIntegral);
        storeOrder.setMark(StringEscapeUtils.escapeHtml4(request.getMark()));
        storeOrder.setCombinationId(request.getCombinationId());
        storeOrder.setPinkId(request.getPinkId());
        storeOrder.setSeckillId(request.getSeckillId());
        storeOrder.setBargainId(request.getBargainId());
        storeOrder.setCost(mapCostPrice);
        storeOrder.setSourceCost(mapSourceCostPrice);
        storeOrder.setIsChannel(isChannel);
        storeOrder.setCreateTime(DateUtil.nowDateTime());
        storeOrder.setUnique(orderKey);
        storeOrder.setShippingType(request.getShippingType());
        storeOrder.setActivityGroupId(request.getActivityGroupId());
        Integer pickingId = cor.getPriceGroup().getPickingId();
        if (pickingId > 0) {
            storeOrder.setStatus(OrderStatusEnum.VERIFY.getCode());
            storeOrder.setPayType("");
        }
        storeOrder.setPickingId(pickingId);
        //积分倍数
        if (storeOrder.getEnableIntegral() == 1) {
            UserMemberRecord member = userMemberRecordService.getUserMember(currentUser.getUid());
            BigDecimal integralMultiples = new BigDecimal(cor.getOther().get(Constants.CONFIG_KEY_INTEGRAL_RATE_ORDER_GIVE).toString());
            if (member != null) {
                MerchantMemberBenefits memberBenefits = merchantMemberBenefitsService.getOne(Wrappers.<MerchantMemberBenefits>lambdaQuery().eq(MerchantMemberBenefits::getMerId, storeOrder.getMerId())
                        .eq(MerchantMemberBenefits::getEquityType, 3)
                        .eq(MerchantMemberBenefits::getEquityEnableFlag, true)
                        .last("LIMIT 1"));
                if (memberBenefits != null) {
                    integralMultiples = integralMultiples.multiply(memberBenefits.getPointsMultiple());
                }
                storeOrder.setIntegralMultiples(integralMultiples);
            }
        }

        // 如果是自提
        if (request.getShippingType() == 2) {
            storeOrder.setToPhone(request.getToPhone());
        }
//        if (request.getShippingType() == 2) {
//            storeOrder.setVerifyCode(CrmebUtil.randomCount(1111111111, 999999999) + "");
//            SystemStore systemStore = new SystemStore();
//            systemStore.setId(request.getStoreId());
//            systemStore.setIsShow(true);
//            systemStore.setIsDel(false);
//            SystemStore existSystemStore = systemStoreService.getByCondition(systemStore);
//            if (null == existSystemStore) {
//                throw new CrmebException("暂无门店无法选择门店自提");
//            }
//            storeOrder.setStoreId(existSystemStore.getId());
//        }

        if (ObjectUtil.isNotEmpty(currentUser)) {
            storeOrder.setCreateName(currentUser.getNickname());
        }
        if ((storeOrder.getCouponId() > 0 || storeOrder.getCouponPrice().compareTo(BigDecimal.ZERO) > 0) && (storeOrder.getDeductionPrice().compareTo(BigDecimal.ZERO) > 0 || storeOrder.getUseIntegral() > 0)) {
            throw new CrmebException("不能同时使用优惠券和积分抵扣");
        }
        // 设置支付人信息
        storeOrder.setPayNo(storeOrder.getOutOrderId());
        storeOrder.setIdCard(request.getIdCard());
        storeOrder.setPayName(request.getIdName());
        //生成订单
        boolean createdResult = storeOrderService.create(storeOrder);
        if (!createdResult) {
            throw new CrmebException("订单生成失败");
        }
        if (couponId > 0) {
            boolean useCouponUser = storeCouponUserService.update(Wrappers.lambdaUpdate(StoreCouponUser.class).eq(StoreCouponUser::getId, storeOrder.getCouponId()).eq(StoreCouponUser::getStatus, 0)
                    .set(StoreCouponUser::getStatus, 1).set(StoreCouponUser::getCid, storeOrder.getId()).set(StoreCouponUser::getUseTime, new Date()));
            if (!useCouponUser) {
                throw new CrmebException("使用优惠卷失败");
            }
        }
    }

    private void addPickingOrderInfo(ConfirmOrderResponse cor, StoreOrder storeOrder, Integer merId) {
        List<StoreOrderInfoPicking> storeOrderInfos = new ArrayList<>();
        boolean deCountResult = true;
        ChannelMerchant merchant = channelMerchantService.getById(merId);
        //满额包邮判断
        List<Integer> freeShippingActivityIds = channelFreeShippingActivityService.getFreeShippingActivityId(cor.getCartInfo(), cor.getAddressInfo(), merId);
        for (StoreCartResponse cartResponse : cor.getCartInfo()) {
            //校验发货地、收货地
            if (merchant.getChannelType() != 8) {
                checkDeliveryAndReceivingAddr(cartResponse.getProductInfo().getTempId(), storeOrder.getAreaType());
            }
            deCountResult = deCountResult && storeProductService.decPickingProductStock(cartResponse.getProductId(), cartResponse.getCartNum(), cartResponse.getProductAttrUnique(), 0); // todo 限购参数
            StoreProductAttrValue attrInfo = cartResponse.getProductInfo().getAttrInfo();
            StoreProduct storeProduct = storeProductService.getById(cartResponse.getProductId());
            Integer isEurope;
            if (Objects.equals(storeProduct.getIsEurope(), ProductTypeEnum.INSIDE.getCode())) {
                isEurope = storeProduct.getConvertIsEurope() == null ? ProductTypeEnum.INSIDE.getCode() : storeProduct.getConvertIsEurope();
                Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
                if (supplier != null && Objects.equals(supplier.getId().toString(), storeProduct.getSuppliersId() + "")) {
                    isEurope = ProductTypeEnum.INSIDE.getCode();
                }
            } else {
                isEurope = storeProduct.getIsEurope();
            }
            // 计算商户成本价和平台成本价
            StoreProductAttrValue storeProductAttrValue = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValue>lambdaQuery()
                    .eq(StoreProductAttrValue::getBarCode, attrInfo.getBarCode())
                    .eq(StoreProductAttrValue::getSourceSkuId, attrInfo.getSourceSkuId())
                    .last("LIMIT 1")
            );
            //商品规格价格处理
            priceUtil.calcProductValuePrice(Collections.singletonList(storeProductAttrValue), merId, storeProduct, storeOrder.getAreaType(),
                    null, true, freeShippingActivityIds, true, cor.getAddressInfo());
            attrInfo.setCost(storeProductAttrValue.getCost());
            attrInfo.setSourceCost(storeProductAttrValue.getSourceCost());
            attrInfo.setOtPrice(storeProductAttrValue.getOtPrice());
            attrInfo.setFirstPrice(storeProductAttrValue.getFirstPrice());
            attrInfo.setSecondPrice(storeProductAttrValue.getSecondPrice());
            attrInfo.setTaxPrice(storeProductAttrValue.getTaxPrice());
            attrInfo.setTaxAndSecondPrice(storeProductAttrValue.getTaxAndSecondPrice());
            attrInfo.setFirstAgentCost(storeProductAttrValue.getFirstAgentCost());
            attrInfo.setSecondAgentCost(storeProductAttrValue.getSecondAgentCost());
            attrInfo.setFirstAgentRatio(storeProductAttrValue.getFirstAgentRatio());
            attrInfo.setSecondAgentRatio(storeProductAttrValue.getSecondAgentRatio());
            attrInfo.setFirstAgentId(storeProductAttrValue.getFirstAgentId());
            attrInfo.setSecondAgentId(storeProductAttrValue.getSecondAgentId());
            //发货时间
            attrInfo.setDeliveryTime(productUtil.getDeliveryTimeByTempId(storeProduct.getTempId(), storeProduct.getIsEurope(), merId, storeProduct.getId()));
            //收货时间
            attrInfo.setReceivingTime(productUtil.getReceivingTime(storeProduct.getTempId(), storeProduct.getIsEurope(), storeProduct.getMerId(), storeProduct.getId()));
            attrInfo.setColorCode(storeProduct.getColorCode());
            attrInfo.setSeasonCode(storeProduct.getSeasonCode());

            StoreOrderInfoPicking soInfo = new StoreOrderInfoPicking();
            soInfo.setOrderId(storeOrder.getId());
            soInfo.setProductId(cartResponse.getProductId());
            //判断自建商品是否为全新还是二手
            if (ProductTypeEnum.INSIDE.getCode().equals(storeProduct.getIsEurope())) {
                if (StringUtils.isEmpty(storeProduct.getDegree())) {
                    soInfo.setNewProductFlag(1);
                } else {
                    soInfo.setNewProductFlag(0);
                }
            }
            //计算商品积分抵扣
            attrInfo.setDeductionPrice(BigDecimal.ZERO);
            //积分数
            attrInfo.setUseIntegral(BigDecimal.ZERO);
            //商品实际支付金额 （售价-积分抵扣金额）
            BigDecimal paidPrice = cartResponse.getTruePrice();
            attrInfo.setProductPaidPrice(paidPrice.subtract(attrInfo.getTaxAndSecondPrice()));
            //商品支付金额
            attrInfo.setPaidPrice(paidPrice);
            attrInfo.setSubTotalPrice(paidPrice);
            //不拆单
            StoreCartResponse storeCartResponse = new StoreCartResponse();
            BeanUtils.copyProperties(cartResponse, storeCartResponse);
            storeCartResponse.setCartNum(1);
            soInfo.setInfo(JSON.toJSON(storeCartResponse).toString());
            //订单是否自建
            soInfo.setIsEurope(isEurope);
            soInfo.setUnique(cartResponse.getProductAttrUnique());
            soInfo.setOrderInfoId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT));
            soInfo.setSuppliersId(storeProduct.getSuppliersId());
            soInfo.setDeliveryAddress(cartResponse.getProductInfo().getTempId() != 1 && !ProductTypeEnum.ORANGE.getCode().equals(cartResponse.getProductInfo().getIsEurope())
                    && !ProductTypeEnum.INSIDE.getCode().equals(cartResponse.getProductInfo().getIsEurope())
                    ? merchant.getDetail()
                    : cor.getAddressInfo().getProvince() + cor.getAddressInfo().getCity() + cor.getAddressInfo().getDistrict() + cor.getAddressInfo().getDetail());
            soInfo.setPayPrice(attrInfo.getPaidPrice());
            soInfo.setExchangeRate(storeProduct.getExchangeRate());
            soInfo.setFirstPrice(attrInfo.getFirstPrice());
            soInfo.setSecondPrice(attrInfo.getSecondPrice());
            soInfo.setTaxPrice(attrInfo.getTaxPrice());
            soInfo.setNum(cartResponse.getCartNum());
            if (attrInfo.getFirstAgentId() != null) {
                if (attrInfo.getSecondAgentId() != null) {
                    soInfo.setFirstAgentProfit(attrInfo.getSecondAgentCost().subtract(attrInfo.getFirstAgentCost()));
                    soInfo.setSecondAgentProfit(attrInfo.getCost().subtract(attrInfo.getSecondAgentCost()));
                } else {
                    soInfo.setFirstAgentProfit(attrInfo.getCost().subtract(attrInfo.getFirstAgentCost()));
                }
            }
            if (soInfo.getIsEurope() != 1 && Objects.equals(merchant.getAutoPush(), 1)) {
                soInfo.setAutonomous(0);
            }
            soInfo.setStoreName(storeProduct.getStoreName());
            soInfo.setKeyword(storeProduct.getKeyword());
            soInfo.setCateId(storeProduct.getCateId());
            soInfo.setPickingProductId(cartResponse.getPickingProductId());
            storeOrderInfos.add(soInfo);
        }
        // 保存购物车商品详情
        boolean saveBatchOrderInfosResult = storeOrderInfoPickingService.saveBatch(storeOrderInfos);
        if (!saveBatchOrderInfosResult && !deCountResult) {
            throw new CrmebException("订单生成失败");
        }
    }

    /**
     * 创建订单 - 订单明细
     *
     * @param cor
     * @param storeOrder
     */
    private void addOrderInfo(ConfirmOrderResponse cor, StoreOrder storeOrder, Integer merId) {
        // todo 库存操作 砍价拼团秒杀 二期
        List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        boolean deCountResult = true;
        ChannelMerchant merchant = channelMerchantService.getById(merId);
        BigDecimal vipDiscountRatio = cor.getPriceGroup().getVipDiscountRatio();
        CalculatePriceVo calculateVo = new CalculatePriceVo();
        if (storeOrder.getCouponPrice().compareTo(BigDecimal.ZERO) > 0) {
            calculateVo = getCalculate(cor, storeOrder, storeOrder.getCouponPrice(), cor.getProductIdList(), false);
        } else if (storeOrder.getDeductionPrice().compareTo(BigDecimal.ZERO) > 0) {
            calculateVo = getCalculate(cor, storeOrder, storeOrder.getDeductionPrice(), cor.getIntegralProductIdList(), false);
        }
        List<VipDiscountVo> vipDiscountList = cor.getVipDiscountList();
        Map<Integer, List<VipDiscountVo>> vipDiscountVoMap = new HashMap<>();
        if (CollectionUtils.isNotEmpty(vipDiscountList) && storeOrder.getVipReducePrice().compareTo(BigDecimal.ZERO) > 0) {
            vipDiscountVoMap = vipDiscountList.stream().collect(Collectors.groupingBy(VipDiscountVo::getProductId));
        }
        //售价降序
        List<StoreCartResponse> sortList = cor.getCartInfo().stream().sorted(Comparator.comparing(StoreCartResponse::getTruePrice).reversed()).collect(Collectors.toList());
        //满额包邮满足条件的活动id
        List<Integer> freeShippingActivityIds = channelFreeShippingActivityService.getFreeShippingActivityId(sortList, cor.getAddressInfo(), merId);
        for (StoreCartResponse cartResponse : sortList) {
            boolean isCoupon = getFlag(cartResponse, cor.getProductIdList());
            boolean isIntegral = getFlag(cartResponse, cor.getIntegralProductIdList());
            //校验发货地、收货地
            if (merchant.getChannelType() != 8) {
                checkDeliveryAndReceivingAddr(cartResponse.getProductInfo().getTempId(), storeOrder.getAreaType());
            }
            deCountResult = deCountResult && storeProductService.decProductStock(cartResponse.getProductId(), cartResponse.getCartNum(), cartResponse.getProductAttrUnique(), 0, storeOrder.getActivityGroupId()); // todo 限购参数
            StoreProductAttrValue attrInfo = cartResponse.getProductInfo().getAttrInfo();
            StoreProduct storeProduct = storeProductService.getById(cartResponse.getProductId());
            Integer isEurope;
            if (Objects.equals(storeProduct.getIsEurope(), ProductTypeEnum.INSIDE.getCode())) {
                isEurope = storeProduct.getConvertIsEurope() == null ? ProductTypeEnum.INSIDE.getCode() : storeProduct.getConvertIsEurope();
                Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
                if (supplier != null && Objects.equals(supplier.getId().toString(), storeProduct.getSuppliersId() + "")) {
                    isEurope = ProductTypeEnum.INSIDE.getCode();
                }
            } else {
                isEurope = storeProduct.getIsEurope();
            }
            // 计算商户成本价和平台成本价
            StoreProductAttrValue storeProductAttrValue = storeProductAttrValueService.getOne(Wrappers.<StoreProductAttrValue>lambdaQuery()
                    .eq(StoreProductAttrValue::getBarCode, attrInfo.getBarCode())
                    .eq(StoreProductAttrValue::getSourceSkuId, attrInfo.getSourceSkuId())
                    .last("LIMIT 1")
            );
            //商品规格价格处理
            priceUtil.calcProductValuePrice(Collections.singletonList(storeProductAttrValue), merId, storeProduct, storeOrder.getAreaType(),
                    null, false, freeShippingActivityIds, cartResponse.getIsBtoC(), cor.getAddressInfo());

            attrInfo.setCost(storeProductAttrValue.getCost());
            attrInfo.setSourceCost(storeProductAttrValue.getSourceCost());
            attrInfo.setOtPrice(storeProductAttrValue.getOtPrice());
            attrInfo.setFirstPrice(storeProductAttrValue.getFirstPrice());
            attrInfo.setSecondPrice(storeProductAttrValue.getSecondPrice());
            attrInfo.setTaxPrice(storeProductAttrValue.getTaxPrice());
            attrInfo.setTaxAndSecondPrice(storeProductAttrValue.getTaxAndSecondPrice());
            attrInfo.setFirstAgentCost(storeProductAttrValue.getFirstAgentCost());
            attrInfo.setSecondAgentCost(storeProductAttrValue.getSecondAgentCost());
            attrInfo.setFirstAgentRatio(storeProductAttrValue.getFirstAgentRatio());
            attrInfo.setSecondAgentRatio(storeProductAttrValue.getSecondAgentRatio());
            attrInfo.setFirstAgentId(storeProductAttrValue.getFirstAgentId());
            attrInfo.setSecondAgentId(storeProductAttrValue.getSecondAgentId());
//            BigDecimal discountPrice = BigDecimal.ZERO;
            Integer type = null;
            if (vipDiscountVoMap.containsKey(cartResponse.getProductId())) {
                List<VipDiscountVo> vipDiscountVoList = vipDiscountVoMap.get(cartResponse.getProductId());
                List<VipDiscountVo> voList = vipDiscountVoList.stream().filter(e -> e.getSourceSkuId().equals(attrInfo.getSourceSkuId())).collect(Collectors.toList());
                if (CollectionUtils.isNotEmpty(voList)) {
                    VipDiscountVo vipDiscountVo = voList.get(0);
//                    discountPrice = vipDiscountVo.getDiscountPrice();
                    type = vipDiscountVo.getType();
                    if (vipDiscountVo.getType() == 0) {
                        attrInfo.setVipDiscountRatio(vipDiscountRatio);
                    }
                }
            }
            //发货时间
            attrInfo.setDeliveryTime(productUtil.getDeliveryTimeByTempId(storeProduct.getTempId(), storeProduct.getIsEurope(), merId, storeProduct.getId()));
            //收货时间
            attrInfo.setReceivingTime(productUtil.getReceivingTime(storeProduct.getTempId(), storeProduct.getIsEurope(), storeProduct.getMerId(), storeProduct.getId()));
            attrInfo.setColorCode(storeProduct.getColorCode());
            attrInfo.setSeasonCode(storeProduct.getSeasonCode());
            //活动id
            Integer activityId = 0;
            ChannelActivity channelActivity = cartResponse.getChannelActivity();
            if (channelActivity != null) {
                activityId = channelActivity.getId();
            }
            //拆单
            for (int i = 0; i < cartResponse.getCartNum(); i++) {
                StoreOrderInfo soInfo = new StoreOrderInfo();
                soInfo.setOrderId(storeOrder.getId());
                soInfo.setProductId(cartResponse.getProductId());
                //判断自建商品是否为全新还是二手
                if (ProductTypeEnum.INSIDE.getCode().equals(storeProduct.getIsEurope())) {
                    if (StringUtils.isEmpty(storeProduct.getDegree())) {
                        soInfo.setNewProductFlag(1);
                    } else {
                        soInfo.setNewProductFlag(0);
                    }
                }
                //优惠券拆分
                calculateVo.setReducePrice(BigDecimal.ZERO);
                getReducePrice(merchant, calculateVo, cartResponse, isCoupon, storeOrder.getCouponPrice(), true, BigDecimal.ZERO);
                //商品抵扣金额
                getReducePrice(merchant, calculateVo, cartResponse, isIntegral, storeOrder.getDeductionPrice(), false, BigDecimal.ZERO);
                //会员
//                vipCalculateVo.setReducePrice(BigDecimal.ZERO);
//                getReducePrice(merchant, vipCalculateVo, cartResponse, isMember, storeOrder.getVipReducePrice(),true,calculateVo.getReducePrice());
                //计算商品积分抵扣
                attrInfo.setDeductionPrice(storeOrder.getDeductionPrice().compareTo(BigDecimal.ZERO) > 0 ? calculateVo.getReducePrice() : BigDecimal.ZERO);
                //积分数
                Object rate = cor.getOther().get(Constants.CONFIG_KEY_INTEGRAL_RATE);
                attrInfo.setUseIntegral(rate != null ? calculateVo.getReducePrice().divide(new BigDecimal(rate.toString()), 0, RoundingMode.DOWN) : BigDecimal.ZERO);
                //商品实际支付金额 （售价-积分抵扣金额）
                BigDecimal discountPrice = type == null ? BigDecimal.ZERO : (type == 0 ? cartResponse.getVipReducePriceList().get(i) : cartResponse.getLevelVipReducePriceList().get(i));
                BigDecimal paidPrice = cartResponse.getTruePrice().subtract(calculateVo.getReducePrice()).subtract(discountPrice);
                attrInfo.setProductPaidPrice(paidPrice.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : paidPrice);
                //商品支付金额
                attrInfo.setPaidPrice(new BigDecimal(paidPrice.add(attrInfo.getTaxAndSecondPrice()).stripTrailingZeros().toPlainString()));
                attrInfo.setSubTotalPrice(attrInfo.getPrice().add(attrInfo.getTaxAndSecondPrice()));
                //只计算限时活动优惠价价
                if (Objects.nonNull(channelActivity)) {
                    BigDecimal activityProductPrice = attrInfo.getPrice().add(attrInfo.getTaxAndSecondPrice()).subtract(attrInfo.getPaidPrice());
                    attrInfo.setActivityProductPrice(activityProductPrice.compareTo(BigDecimal.ZERO) >= 0 ? activityProductPrice : BigDecimal.ZERO);
                } else if (Objects.nonNull(cartResponse.getActivityGroupId())) {
                    BigDecimal activityProductPrice = attrInfo.getPrice().add(attrInfo.getTaxAndSecondPrice()).subtract(attrInfo.getPaidPrice());
                    attrInfo.setActivityProductPrice(activityProductPrice.compareTo(BigDecimal.ZERO) >= 0 ? activityProductPrice : BigDecimal.ZERO);
                }
                StoreCartResponse storeCartResponse = new StoreCartResponse();
                BeanUtils.copyProperties(cartResponse, storeCartResponse);
                storeCartResponse.setCartNum(1);
                storeCartResponse.setDiscountInfo(cor.getDiscountInfo());
                // todo 兜底barCode
                if (null!=storeCartResponse.getProductInfo()&&null!=storeCartResponse.getProductInfo().getAttrInfo()
                        &&StringUtils.isBlank(storeCartResponse.getProductInfo().getAttrInfo().getBarCode())){
                    storeCartResponse.getProductInfo().getAttrInfo().setBarCode(storeProduct.getBarCode());
                }
                soInfo.setInfo(JSON.toJSON(storeCartResponse).toString());
                //订单是否自建
                soInfo.setIsEurope(isEurope);
                soInfo.setUnique(cartResponse.getProductAttrUnique());
                soInfo.setOrderInfoId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT));
                soInfo.setSuppliersId(storeProduct.getSuppliersId());
                soInfo.setDeliveryAddress(cartResponse.getProductInfo().getTempId() != 1 && !ProductTypeEnum.ORANGE.getCode().equals(cartResponse.getProductInfo().getIsEurope())
                        && !ProductTypeEnum.INSIDE.getCode().equals(cartResponse.getProductInfo().getIsEurope())
                        ? merchant.getDetail()
                        : cor.getAddressInfo().getProvince() + cor.getAddressInfo().getCity() + cor.getAddressInfo().getDistrict() + cor.getAddressInfo().getDetail());
                if (storeOrder.getShippingType() == 2) {
                    soInfo.setVerifyCode(CrmebUtil.randomCount(1111111111, 999999999) + "");
                }
                soInfo.setPayPrice(attrInfo.getPaidPrice());
                soInfo.setDeductionPrice(attrInfo.getDeductionPrice());
                soInfo.setExchangeRate(storeProduct.getExchangeRate());
                soInfo.setFirstPrice(attrInfo.getFirstPrice());
                soInfo.setSecondPrice(attrInfo.getSecondPrice());
                soInfo.setTaxPrice(attrInfo.getTaxPrice());
                soInfo.setCouponPrice(storeOrder.getCouponPrice().compareTo(BigDecimal.ZERO) > 0 ? calculateVo.getReducePrice() : BigDecimal.ZERO);
                soInfo.setVipReducePrice(discountPrice);
                if (attrInfo.getFirstAgentId() != null) {
                    if (attrInfo.getSecondAgentId() != null) {
                        soInfo.setFirstAgentProfit(attrInfo.getSecondAgentCost().subtract(attrInfo.getFirstAgentCost()));
                        soInfo.setSecondAgentProfit(attrInfo.getCost().subtract(attrInfo.getSecondAgentCost()));
                    } else {
                        soInfo.setFirstAgentProfit(attrInfo.getCost().subtract(attrInfo.getFirstAgentCost()));
                    }
                }
                if (soInfo.getIsEurope() != 1 && Objects.equals(merchant.getAutoPush(), 1)) {
                    soInfo.setAutonomous(0);
                }
                soInfo.setStoreName(storeProduct.getStoreName());
                soInfo.setKeyword(storeProduct.getKeyword());
                soInfo.setCateId(storeProduct.getCateId());
                soInfo.setActivityId(activityId);
                soInfo.setRealPlatRatio(cartResponse.getRealPlatRatio());
                soInfo.setSuppliersRatio(cartResponse.getSuppliersRatio());
                storeOrderInfos.add(soInfo);
            }
        }
        // 赠品信息
        List<StoreProduct> giftProductInfos = JSON.parseArray(JSON.toJSONString(cor.getDiscountInfo().get("giftProductInfos")), StoreProduct.class);
        for (StoreProduct storeProduct : giftProductInfos) {
            // 几件赠品
            for (int i = 0; i < storeProduct.getSales(); i++) {
                StoreOrderInfo soInfo = new StoreOrderInfo();
                soInfo.setOrderId(storeOrder.getId());
                soInfo.setProductId(storeProduct.getId());
                //判断自建商品是否为全新还是二手
                if (ProductTypeEnum.INSIDE.getCode().equals(storeProduct.getIsEurope())) {
                    if (StringUtils.isEmpty(storeProduct.getDegree())) {
                        soInfo.setNewProductFlag(1);
                    } else {
                        soInfo.setNewProductFlag(0);
                    }
                }
                StoreCartResponse storeCartResponse = new StoreCartResponse();
                storeCartResponse.setCartNum(1);
                storeCartResponse.setDiscountInfo(cor.getDiscountInfo());
                //后续查询需要获取的信息
                StoreProductAttrValue attrInfo = new StoreProductAttrValue();
                attrInfo.setCost(storeProduct.getCost());
                attrInfo.setSourceCost(storeProduct.getSourceCost());
                attrInfo.setOtPrice(storeProduct.getOtPrice());
                attrInfo.setImage(storeProduct.getImage());
                attrInfo.setProductPaidPrice(BigDecimal.ZERO);
                attrInfo.setPaidPrice(BigDecimal.ZERO);
                attrInfo.setDeductionPrice(BigDecimal.ZERO);
                attrInfo.setUseIntegral(BigDecimal.ZERO);
                attrInfo.setActivityProductPrice(BigDecimal.ZERO);
                attrInfo.setSubTotalPrice(BigDecimal.ZERO);
                attrInfo.setPrice(BigDecimal.ZERO);
                attrInfo.setSecondPrice(BigDecimal.ZERO);
                attrInfo.setTaxPrice(BigDecimal.ZERO);
                attrInfo.setSuk("giftProduct");
                StoreProductCartProductInfoResponse productInfo = new StoreProductCartProductInfoResponse();
                productInfo.setAttrInfo(attrInfo);
                productInfo.setStoreName(storeProduct.getStoreName());
                productInfo.setTempId(storeProduct.getTempId());
                productInfo.setBrandName(storeProduct.getBrandName());
                productInfo.setKeyword(storeProduct.getKeyword());
                productInfo.setImage(storeProduct.getImage());
                storeCartResponse.setProductInfo(productInfo);
                soInfo.setInfo(JSON.toJSON(storeCartResponse).toString());
                //订单是否自建
                Integer isEurope;
                if (Objects.equals(storeProduct.getIsEurope(), ProductTypeEnum.INSIDE.getCode())) {
                    isEurope = storeProduct.getConvertIsEurope() == null ? ProductTypeEnum.INSIDE.getCode() : storeProduct.getConvertIsEurope();
                    Supplier supplier = supplierService.getOne(Wrappers.<Supplier>lambdaQuery().eq(Supplier::getMerId, merId));
                    if (supplier != null && Objects.equals(supplier.getId().toString(), storeProduct.getSuppliersId() + "")) {
                        isEurope = ProductTypeEnum.INSIDE.getCode();
                    }
                } else {
                    isEurope = storeProduct.getIsEurope();
                }
                soInfo.setIsEurope(isEurope);
                soInfo.setUnique("giftProduct");
                soInfo.setOrderInfoId(CrmebUtil.getOrderNo(Constants.PAY_TYPE_WE_CHAT));
                soInfo.setSuppliersId(storeProduct.getSuppliersId());
                soInfo.setDeliveryAddress(storeProduct.getTempId() != 1 && !ProductTypeEnum.ORANGE.getCode().equals(storeProduct.getIsEurope())
                        && !ProductTypeEnum.INSIDE.getCode().equals(storeProduct.getIsEurope())
                        ? merchant.getDetail()
                        : cor.getAddressInfo().getProvince() + cor.getAddressInfo().getCity() + cor.getAddressInfo().getDistrict() + cor.getAddressInfo().getDetail());
                if (storeOrder.getShippingType() == 2) {
                    soInfo.setVerifyCode(CrmebUtil.randomCount(1111111111, 999999999) + "");
                }
                soInfo.setPayPrice(BigDecimal.ZERO);
                soInfo.setDeductionPrice(BigDecimal.ZERO);
                soInfo.setExchangeRate(BigDecimal.ZERO);
                soInfo.setFirstPrice(BigDecimal.ZERO);
                soInfo.setSecondPrice(BigDecimal.ZERO);
                soInfo.setTaxPrice(BigDecimal.ZERO);
                soInfo.setCouponPrice(BigDecimal.ZERO);
                soInfo.setVipReducePrice(BigDecimal.ZERO);
                if (soInfo.getIsEurope() != 1 && Objects.equals(merchant.getAutoPush(), 1)) {
                    soInfo.setAutonomous(0);
                }
                soInfo.setStoreName(storeProduct.getStoreName());
                soInfo.setKeyword(storeProduct.getKeyword());
                soInfo.setCateId(storeProduct.getCateId());
                storeOrderInfos.add(soInfo);
            }
        }
        // 保存购物车商品详情
        boolean saveBatchOrderInfosResult = storeOrderInfoService.saveOrderInfos(storeOrderInfos);
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, storeOrder.getId()));
        orderInfoList.forEach(e -> e.setChildOrderNumber(Long.toString(Long.parseLong(storeOrder.getId() + "" + e.getId()), 36).toUpperCase()));
        storeOrderInfoService.updateBatchById(orderInfoList);
        if (!saveBatchOrderInfosResult && !deCountResult) {
            throw new CrmebException("订单生成失败");
        }
    }

    private boolean getFlag(StoreCartResponse cartResponse, List<Integer> productIdList) {
        boolean isCoupon = false;
        if (CollectionUtils.isNotEmpty(productIdList)) {
            isCoupon = productIdList.contains(cartResponse.getProductId());
        }
        return isCoupon;
    }

    private void getReducePrice(ChannelMerchant merchant, CalculatePriceVo calculateVo, StoreCartResponse cartResponse, boolean isMember, BigDecimal price, boolean appletType, BigDecimal creditPrice) {
        if (price.compareTo(BigDecimal.ZERO) > 0) {
            if (isMember) {
                BigDecimal reducePrice = BigDecimal.ZERO;
                int vipFlag = calculateVo.getFlag();
                BigDecimal amount = calculateVo.getAmount();
                if (vipFlag < calculateVo.getSum()) {
                    if (appletType && merchant.getAppletType() == 1) {
                        reducePrice = (cartResponse.getTruePrice().add(cartResponse.getTaxAndSecondPrice()).subtract(creditPrice)).multiply(price).divide(calculateVo.getPayPrice(), 0, RoundingMode.UP);
                    } else {
                        reducePrice = (cartResponse.getTruePrice().subtract(creditPrice)).multiply(price).divide(calculateVo.getTotalPrice(), 0, RoundingMode.UP);
                    }
                    if (price.compareTo(amount.add(reducePrice)) < 0) {
                        reducePrice = price.subtract(amount);
                    }
                    amount = amount.add(reducePrice);
                } else if (vipFlag == calculateVo.getSum()) {
                    reducePrice = price.subtract(amount);
                }
                vipFlag++;
                calculateVo.setAmount(amount);
                calculateVo.setFlag(vipFlag);
                calculateVo.setReducePrice(reducePrice);
            }
        }
    }

    private CalculatePriceVo getCalculate(ConfirmOrderResponse cor, StoreOrder storeOrder, BigDecimal price, List<Integer> productIdList, boolean isVip) {
        CalculatePriceVo calculateVo = new CalculatePriceVo();
        if (price.compareTo(BigDecimal.ZERO) > 0) {
            if (CollectionUtils.isNotEmpty(productIdList)) {
                List<StoreCartResponse> storeCartResponseList = cor.getCartInfo().stream().filter(e -> productIdList.contains(e.getProductId())).collect(Collectors.toList());
                calculateVo.setSum(storeCartResponseList.stream().mapToInt(StoreCartResponse::getCartNum).sum());
                BigDecimal totalPrice = storeCartResponseList.stream().map(storeCartResponse -> storeCartResponse.getTruePrice().multiply(new BigDecimal(storeCartResponse.getCartNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
                BigDecimal payPrice = storeCartResponseList.stream().map(storeCartResponse -> (storeCartResponse.getTruePrice().add(storeCartResponse.getTaxAndSecondPrice())).multiply(new BigDecimal(storeCartResponse.getCartNum()))).reduce(BigDecimal.ZERO, BigDecimal::add);
                calculateVo.setTotalPrice(totalPrice);
                calculateVo.setPayPrice(payPrice);
                if (isVip) {
//                    BigDecimal cutPrice = storeOrder.getDeductionPrice().add(storeOrder.getCouponPrice());
                    calculateVo.setTotalPrice(totalPrice.subtract(price));
                    calculateVo.setPayPrice(payPrice.subtract(price));
                }
                calculateVo.setFlag(1);
                calculateVo.setAmount(BigDecimal.ZERO);
            }
        }
        return calculateVo;
    }

    /**
     * 校验发货地和收货地
     */
    private void checkDeliveryAndReceivingAddr(Integer tempId, Integer areaType) {
        /* 以下情况生成订单失败
            1.发货地大陆，收货地香港、欧洲
            2.发货地香港，收货地欧洲
            3.发货地欧洲，收货地欧洲
         */
        //收货地海外
        if (AreaTypeEnum.ABROAD.getType().equals(areaType)) {
            throw new CrmebException("收货地址暂不支持海外");
        }
        //收货地香港 大陆发货
        if (AreaTypeEnum.HK.getType().equals(areaType) && StockAreaTempEnum.CN.getTempId().equals(tempId)) {
            throw new CrmebException("暂不支持大陆发往香港的订单");
        }
    }

    /**
     * 创建订单 - 积分抵扣
     */
    private void deductionScore(OrderCreateRequest request, ConfirmOrderResponse cor, User currentUser, Integer orderId) {
        // todo 秒杀产品占用库存
        if (cor.getPriceGroup().getEnableIntegral() == 0) return;
        if (cor.getPriceGroup().getUsedIntegral() == 0) return;
        currentUser.setIntegral(currentUser.getIntegral().subtract(new BigDecimal(cor.getPriceGroup().getUsedIntegral())));
        if (currentUser.getIntegral().compareTo(BigDecimal.ZERO) < 0) throw new CrmebException("积分不足");
        userService.updateBase(currentUser);
        /*if (request.getUseIntegral() && currentUser.getIntegral().compareTo(BigDecimal.ZERO) > 0) {

         *//*UserBill userBill = new UserBill();
            userBill.setTitle("积分冻结");
            userBill.setUid(currentUser.getUid());
            userBill.setCategory("integral");
            userBill.setType("deduction");
            userBill.setNumber(new BigDecimal(cor.getPriceGroup().getUsedIntegral()));
            userBill.setLinkId(orderId + "");
            userBill.setBalance(currentUser.getIntegral());

            userBill.setMark("创建订单冻结" + userBill.getNumber() + "积分");
            boolean userBillSaveResult = userBillService.save(userBill);
            disIntegle = disIntegle && userBillSaveResult;*//*
        }*/


    }


    /**
     * 创建订单 - 删除购物车
     */
    private void deleteCartInfo(ConfirmOrderResponse cor, User currentUser, StoreOrder storeOrder, String orderKey) {
        // todo 删除购物车信息
        if (storeOrder.getPickingId() > 0) {
            storeCartService.remove(Wrappers.<StoreCart>lambdaQuery().eq(StoreCart::getPickingId, storeOrder.getPickingId())
                    .eq(StoreCart::getUid, currentUser.getUid()));
        } else {
            List<Long> ids = cor.getCartInfo().stream().map(StoreCartResponse::getId).distinct().collect(Collectors.toList());
            List<Integer> idsInt = ids.stream().map(e -> e.intValue()).distinct().collect(Collectors.toList());
            storeCartService.deleteCartByIds(idsInt);
        }

        // 删除缓存订单
        cacheDeleteOrderInfo(currentUser.getUid(), orderKey);
        // 检查缺省的默认地址设置
        UserAddress defaultAddress = userAddressService.getDefault();
        if (null != defaultAddress) {
            userAddressService.def(cor.getAddressInfo().getId());
        }
        storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(), Constants.ORDER_STATUS_CACHE_CREATE_ORDER, "订单生成");
    }

    /**
     * 获取可用优惠券
     *
     * @param storeCartResponse 购物车参数
     * @return 可用优惠券集合
     */
    public List<StoreCouponUserResponse> getCanUseCouponList(List<StoreCartResponse> storeCartResponse,
                                                             boolean isFilter,
                                                             PriceGroupResponse priceGroupResponse,
                                                             UserAddress address,
                                                             ChannelMerchant channelMerchant) {
        FrontStoreCouponUserRequest request = new FrontStoreCouponUserRequest();
        request.setUserId(userService.getUserIdException());
        // 根据优惠券使用额度筛选优惠券
        return frontCouponUserService.getCanUseUserCouponList(storeCartResponse, request, isFilter, priceGroupResponse, address, channelMerchant);
    }

    /**
     * 检查订单是否重复提交
     *
     * @param orderId 订单id
     * @return 重复提交结果
     */
    public boolean checkOrderSubmitAgain(String orderId) {
        StoreOrderSearchRequest storeOrderSearchRequest = new StoreOrderSearchRequest();
        storeOrderSearchRequest.setOrderId(orderId + "");
        storeOrderSearchRequest.setUid(userService.getUserIdException());
        PageParamRequest pageParamRequest = new PageParamRequest();
        pageParamRequest.setLimit(999);
        pageParamRequest.setPage(1);
        return storeOrderService.getList(storeOrderSearchRequest, pageParamRequest).size() > 0;
    }

    /**
     * 封装现有支付方式
     *
     * @return 支付方式集合
     */
    public List<String> getPayType() {
        List<String> payType = new ArrayList<>();
        payType.add(Constants.PAY_TYPE_WE_CHAT);
        payType.add(Constants.PAY_TYPE_YUE);
        payType.add(Constants.PAY_TYPE_OFFLINE);
        payType.add(Constants.PAY_TYPE_ALI_PAY);
        return payType;
    }

    /**
     * 判断订单是否存在
     *
     * @param orderKey orderKey
     * @return 结果
     */
    public Boolean checkOrderExist(String orderKey, int userId) {
        // 判断订单是否 利用分页api放大参数查询
//        StoreOrderSearchRequest request = new StoreOrderSearchRequest();
//        request.setUid(userService.getUserIdException());
//        request.setOrderId(orderKey);
//        request.setUid(userId);
//        request.setIsDel(false);
//        PageParamRequest paramRequest = new PageParamRequest();
//        paramRequest.setLimit(999);
//        paramRequest.setPage(1);
//        List<StoreOrder> existOrderList = storeOrderService.getList(request, new PageParamRequest());
        StoreOrder storeOrderPram = new StoreOrder();
        storeOrderPram.setUnique(orderKey);
        storeOrderPram.setUid(userId);
        List<StoreOrder> existOrderList = storeOrderService.getByEntity(storeOrderPram);
        return existOrderList.size() > 0;
    }

    /**
     * 检查支付类型
     *
     * @param payType 支付类型标识
     * @return 是否支持
     */
    public Boolean checkPayType(String payType) {
        boolean result = false;
        payType = payType.toLowerCase();
        switch (payType) {
            case Constants.PAY_TYPE_WE_CHAT:
                result = systemConfigService.getValueByKey("pay_weixin_open").equals("1");
                break;
            case Constants.PAY_TYPE_WE_CHAT_NATIVE:
                result = systemConfigService.getValueByKey("pay_weixin_open").equals("1");
                break;
            case Constants.PAY_TYPE_ORAGE_PAY:
                result = systemConfigService.getValueByKey("pay_weixin_open").equals("1");
                break;
            case Constants.PAY_TYPE_YUE:
                result = (systemConfigService.getValueByKey("balance_func_status").equals("1") && systemConfigService.getValueByKey("yue_pay_status").equals("1"));
                break;
            case Constants.PAY_TYPE_OFFLINE:
                result = systemConfigService.getValueByKey("offline_pay_status").equals("1");
                break;
            case Constants.PAY_TYPE_HK_PAY:
                result = systemConfigService.getValueByKey("pay_weixin_open").equals("1");
                break;
            case Constants.PAY_TYPE_ADAPAY_DEGREE:
                result = systemConfigService.getValueByKey("pay_adapay_degree").equals("1");
                break;
            case Constants.PAY_TYPE_ADAPAY_CN:
                result = systemConfigService.getValueByKey("pay_adapay_cn").equals("1");
                break;
            case Constants.PAY_TYPE_LIANLIAN_DEGREE:
                // TODO Lianlian
                result = systemConfigService.getValueByKey("pay_lianlian_degree").equals("1");
                break;

        }
        return result;
    }

    /**
     * 根据所属商户查询使用支付方式
     *
     * @author daigb
     * @date: 2022-07-26 10:38
     */
    public PayTypeEnum getOrderPayType(Integer merId) {

        PayTypeEnum payType = PayTypeEnum.ORANGE;

        /*// 连连支付 TODO 这里暂时写死
        if (merId != null && (merId == 78 || merId == 30)) {
            payType = PayTypeEnum.LIANLIAN_DEGREE;
            return payType;
        }*/
        // 连连支付
        if (-1 != lianlianMerIds.indexOf(merId)) {
            payType = PayTypeEnum.LIANLIAN_DEGREE;
            return payType;
        }
        // 微信支付
        if (-1 != wxMerIds.indexOf(merId)) {
            payType = PayTypeEnum.WEIXIN;
            return payType;
        }
        // aligogo 香港支付
        if (-1 != wxHKMerIds.indexOf(merId)) {
            payType = PayTypeEnum.HK_PAY_ALIGOGO;
            return payType;
        }
        // 汇付聚合
        if (-1 != adapayDegreeMerIds.indexOf(merId)) {
            payType = PayTypeEnum.ADAPAY_DEGREE;
            return payType;
        }
        // 汇付国内
        if (-1 != adapayCnMerIds.indexOf(merId)) {
            payType = PayTypeEnum.ADAPAY_CN;
            return payType;
        }

        return payType;
    }

    /**
     * 缓存订单信息
     *
     * @param userId               用户id
     * @param confirmOrderResponse 确认订单对象
     * @return 缓存结果
     */
    public String cacheSetOrderInfo(Integer userId, ConfirmOrderResponse confirmOrderResponse) {
        String key = DigestUtils.md5Hex(DateUtil.getNowTime().toString());
        // TODO DIDIOK PRICE -2
        redisUtil.set("user_order_" + userId + key, JSONObject.toJSONString(confirmOrderResponse), Constants.ORDER_CASH_CONFIRM, TimeUnit.MINUTES);
        return key;
    }

    /**
     * 获取已缓存的订单信息
     *
     * @param userId   用户id
     * @param cacheKey 缓存key
     * @return 订单确认对象JSON
     */
    public String cacheGetOrderInfo(Integer userId, String cacheKey) {
        // TODO DIDIOK PRICE -1
        String key = "user_order_" + userId + cacheKey;
        boolean exists = redisUtil.exists(key);
        if (!exists) {
            return null;
        }
        return redisUtil.get(key).toString();
    }

    /**
     * 删除缓存订单信息
     *
     * @param userId   用户id
     * @param cacheKey 缓存key
     */
    public void cacheDeleteOrderInfo(Integer userId, String cacheKey) {
        String key = "user_order_" + userId + cacheKey;
        boolean exists = redisUtil.exists(key);
        if (!exists) {
            return;
        }
        redisUtil.remove(key);
    }

    /**
     * 更新当前订单结算信息 切换收货地址以及积分抵扣后支付金额可能会变动
     *
     * @param orderKey
     * @param userId
     * @param confirmOrderResponse
     */
    public void cacheRepliceOrderInfo(String orderKey, Integer userId, ConfirmOrderResponse confirmOrderResponse) {
        String key = "user_order_" + userId + orderKey;
        if (redisUtil.exists(key)) {
            redisUtil.remove(key);
        }
        redisUtil.set(key, JSONObject.toJSONString(confirmOrderResponse), Constants.ORDER_CASH_CONFIRM, TimeUnit.MINUTES);
    }

    /**
     * 根据订单号查询订单信息
     *
     * @param id 订单id
     * @return 计算后的价格集合
     */
    public StoreOrder getInfoById(Integer id) {
        StoreOrder storeOrder = storeOrderService.getById(id);
        Integer userId = userService.getUserIdException();

        if (null == storeOrder || !userId.equals(storeOrder.getUid())) {
            //订单号错误
            throw new CrmebException("没有找到相关订单信息!");
        }

        return storeOrder;
    }

    /**
     * 获取子订单信息
     *
     * @param id
     * @return
     */
    public StoreOrderInfo getStoreOrderInfoById(Integer id) {
        StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(id);

        if (null == storeOrderInfo) {
            //订单号错误
            throw new CrmebException("没有找到相关订单信息!");
        }
        StoreOrder storeOrder = storeOrderService.getById(storeOrderInfo.getOrderId());
        Integer userId = userService.getUserIdException();
        if (!userId.equals(storeOrder.getUid())) {
            throw new CrmebException("没有找到相关订单信息!");
        }
        return storeOrderInfo;
    }

    /**
     * 支付类型
     *
     * @param type 支付类型
     * @return null余额支付  true平台支付   false商家支付/线下支付
     */
    public Boolean getPayType(String type) {
        Boolean payType;
        if (Constants.PAY_TYPE_YUE.equals(type)) {
            payType = null;
        } else {
            payType = Constants.PAY_TYPE_ORAGE_PAY.equals(type);
        }
        return payType;
    }

    /**
     * 修改总订单状态
     *
     * @param id 总订单id
     * @return
     */
    public void updateOrderStatus(Integer id) {
        List<StoreOrderInfo> storeOrderInfoList = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, id));
        //全部退款
        List<StoreOrderInfo> unRefundList = storeOrderInfoList.stream().filter(e -> !e.getStatus().equals(OrderStatusEnum.REJECTED_SUCCESS.getCode()))
                .collect(Collectors.toList());
        StoreOrder storeOrder = storeOrderService.getById(id);
        if (CollectionUtils.isEmpty(unRefundList)) {
            storeOrder.setStatus(OrderStatusEnum.REJECTED_SUCCESS.getCode());
            storeOrderService.updateById(storeOrder);
            //修改冻结订单
            merFreezeBillService.update(Wrappers.<MerFreezeBill>lambdaUpdate().set(MerFreezeBill::getStartThawTime, new Date())
                    .eq(MerFreezeBill::getOrderId, id).gt(MerFreezeBill::getAmountFrozen, 0));
            // 推送订单取消状态到吉客云
            int merId = storeOrder.getMerId();
            if (18 == merId || 30 == merId || 45 == merId || 47 == merId) {
                AbstractStoreOrderService storeOrderService = storeOrderFactory.getStoreOrderService(BarCodeEnum.JKY);
                storeOrderService.cancelChannelOrder(storeOrder, null);
            }
        } else {
            List<StoreOrderInfo> unfinishedList = unRefundList.stream().filter(e -> !e.getStatus().equals(OrderStatusEnum.COMPLETE.getCode()))
                    .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(unfinishedList)) {
                storeOrder.setStatus(OrderStatusEnum.COMPLETE.getCode());
                storeOrderService.updateById(storeOrder);
                //修改冻结订单
                merFreezeBillService.update(Wrappers.<MerFreezeBill>lambdaUpdate().set(MerFreezeBill::getStartThawTime, new Date())
                        .eq(MerFreezeBill::getOrderId, id));
                agentFreezeBillService.update(Wrappers.<AgentFreezeBill>lambdaUpdate().set(AgentFreezeBill::getStartThawTime, new Date())
                        .eq(AgentFreezeBill::getOrderId, id));
                setIntegral(storeOrder);
                //后续操作放入redis
                redisUtil.lPush(Constants.ORDER_TASK_REDIS_KEY_AFTER_TAKE_BY_USER, id);
            }
        }
    }

    private void setIntegral(StoreOrder storeOrder) {
//        String integralRateOrderGive = systemConfigService.getValueByKey(Constants.CONFIG_KEY_INTEGRAL_RATE_ORDER_GIVE);
        try {
            if (storeOrder.getEnableIntegral() == 0) {
                return;
            }
            //查询此订单完成的金额
            List<StoreOrderInfo> list = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, storeOrder.getId())
                    .eq(StoreOrderInfo::getStatus, OrderStatusEnum.COMPLETE));
            BigDecimal reduce = list.stream().map(StoreOrderInfo::getPayPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            if (reduce.compareTo(BigDecimal.ZERO) < 1) {
                return;
            }
            UserOperateFundsRequest userOperateFundsRequest = new UserOperateFundsRequest();
            userOperateFundsRequest.setLinkId(storeOrder.getId() + "");
            userOperateFundsRequest.setFoundsType(Constants.ORDER_STATUS_BARGAIN);
            userOperateFundsRequest.setUid(storeOrder.getUid());
            userOperateFundsRequest.setValue(reduce.multiply(storeOrder.getIntegralMultiples()));
            userOperateFundsRequest.setTitle(Constants.ORDER_STATUS_STR_TAKE);
            userOperateFundsRequest.setFoundsCategory(Constants.USER_BILL_CATEGORY_INTEGRAL);
            userOperateFundsRequest.setType(1);
            userService.updateFounds(userOperateFundsRequest, true);
        } catch (Exception e) {
            throw new CrmebException("更新积分失败" + e.getMessage());
        }
    }

    /**
     * 检测订单是否可以删除
     *
     * @param orderStatus 订单状态
     * @return 计算后的价格集合
     */
    public void checkDeleteStatus(String orderStatus) {
        //退款状态，持可以添加

        String[] deleteStatusList = {
                Constants.ORDER_STATUS_CANCEL,
                Constants.ORDER_STATUS_REFUNDED,
                Constants.ORDER_STATUS_COMPLETE
        };

        if (!Arrays.asList(deleteStatusList).contains(orderStatus)) {
            throw new CrmebException("该订单无法删除,只允许删除已取消、已退款和已完成");
        }
    }


    /**
     * 缓存再次下单数据
     *
     * @param cacheKey        key
     * @param orderAgainCache 再次下单数据
     */
    public void setCacheOrderAgain(String cacheKey, List<StoreCartResponse> orderAgainCache) {
        String d = JSONObject.toJSONString(orderAgainCache);
        redisUtil.set(cacheKey + "", d, Constants.ORDER_CASH_CONFIRM, TimeUnit.MINUTES);
    }

    /**
     * 获取再次下单缓存数据
     *
     * @param cacheKey key
     */
    public List<StoreCartResponse> getCacheOrderAgain(String cacheKey) {
        if (!redisUtil.exists(cacheKey)) {
            return null;
        }
        return JSONObject.parseArray(redisUtil.get(cacheKey).toString(), StoreCartResponse.class);
    }

    /**
     * 翻译支付方式给前端
     *
     * @param payType
     * @return
     */
    private String getOrderPayTypeStr(String payType) {
        String payTypeStr = null;
        switch (payType) {
            case Constants.PAY_TYPE_WE_CHAT:
                payTypeStr = "微信支付";
                break;
            case Constants.PAY_TYPE_YUE:
                payTypeStr = "余额支付";
                break;
            case Constants.PAY_TYPE_OFFLINE:
                payTypeStr = "线下支付";
                break;
            case Constants.PAY_TYPE_ALI_PAY:
                payTypeStr = "支付宝支付";
                break;
            case Constants.PAY_TYPE_HK_PAY:
                payTypeStr = "香港支付";
                break;
            default:
                payTypeStr = "其他支付方式";
                break;
        }
        return payTypeStr;
    }

    /**
     * 根据订单状态获取订单数量
     *
     * @return
     */
    public Integer getCurrentCount(String status, StoreOrderCountItemResponse itemResponse) {
        Integer currentCount = 0;
        switch (status) {
            case Constants.ORDER_STATUS_ALL:
                currentCount = itemResponse.getAll();
                break;
            case Constants.ORDER_STATUS_UNPAID: //未支付
                currentCount = itemResponse.getUnPaid();
                break;
            case Constants.ORDER_STATUS_NOT_SHIPPED: //未发货
                currentCount = itemResponse.getNotShipped();
                break;
            case Constants.ORDER_STATUS_SPIKE: //待收货
                currentCount = itemResponse.getSpike();
                break;
            case Constants.ORDER_STATUS_COMPLETE: //交易完成
                currentCount = itemResponse.getComplete();
                break;
            case Constants.ORDER_STATUS_CANCEL: //取消
                currentCount = itemResponse.getCancel();
                break;
            case Constants.ORDER_STATUS_REFUNDING: //退款中
                currentCount = itemResponse.getRefunding();
                break;
            case Constants.ORDER_STATUS_REFUNDED: //退货退款
                currentCount = itemResponse.getRefunded();
                break;
            case Constants.ORDER_STATUS_REFUNDED_PART: //补偿性退款
                currentCount = itemResponse.getRefundedPart();
                break;
            case Constants.ORDER_STATUS_CONFIRM: //待确认
                currentCount = itemResponse.getConfirm();
                break;
        }
        return currentCount;
    }

    public List<StoreOrderInfo> createPickingOrderInfo(StoreOrder storeOrder) {
        if (storeOrder.getPickingId() > 0 && Objects.equals(storeOrder.getStatus(), OrderStatusEnum.VERIFY.getCode())) {
            ChannelPicking picking = channelPickingService.getById(storeOrder.getPickingId());
            if (storeOrder.getPayPrice().compareTo(picking.getMinimumPrice()) < 0) {
                throw new CrmebException("支付失败，订单金额未达到起订金额");
            }
            List<StoreOrderInfoPicking> infoPickingList = storeOrderInfoPickingService.list(Wrappers.<StoreOrderInfoPicking>lambdaQuery()
                    .eq(StoreOrderInfoPicking::getOrderId, storeOrder.getId())
                    .eq(StoreOrderInfoPicking::getIsDel, 0));
            if (CollectionUtils.isEmpty(infoPickingList)) {
                throw new CrmebException("订单异常");
            }
            int count = storeOrderInfoService.count(Wrappers.<StoreOrderInfo>lambdaQuery().eq(StoreOrderInfo::getOrderId, storeOrder.getId()));
            if (count > 0) {
                throw new CrmebException("订单已存在");
            }
            List<StoreOrderInfo> infoList = new ArrayList<>();
            boolean deCountResult = true;
            for (StoreOrderInfoPicking storeOrderInfoPicking : infoPickingList) {
                deCountResult = deCountResult && storeProductService.decProductStock(storeOrderInfoPicking.getProductId(), storeOrderInfoPicking.getNum(), storeOrderInfoPicking.getUnique(), 0, null); // todo 限购参数
                for (int i = 0; i < storeOrderInfoPicking.getNum(); i++) {
                    StoreOrderInfo info = new StoreOrderInfo();
                    BeanUtils.copyProperties(storeOrderInfoPicking, info, "id");
                    if (storeOrder.getShippingType() == 2) {
                        info.setVerifyCode(CrmebUtil.randomCount(1111111111, 999999999) + "");
                    }
                    info.setCreateTime(new Date());
                    infoList.add(info);
                }
            }
            // 保存购物车商品详情
            boolean saveBatchOrderInfosResult = false;
            List<StoreOrderInfo> orderInfoList = new ArrayList<>();
            if (deCountResult) {
                saveBatchOrderInfosResult = storeOrderInfoService.saveBatch(infoList);
                orderInfoList = storeOrderInfoService.list(Wrappers.lambdaQuery(StoreOrderInfo.class).eq(StoreOrderInfo::getOrderId, storeOrder.getId()));
                orderInfoList.forEach(e -> e.setChildOrderNumber(Long.toString(Long.parseLong(storeOrder.getId() + "" + e.getId()), 36).toUpperCase()));
                storeOrderInfoService.updateBatchById(orderInfoList);
            }
            if (!saveBatchOrderInfosResult) {
                throw new CrmebException("订单生成失败");
            }
            storeOrder.setStatus(0);
            storeOrderService.update(Wrappers.<StoreOrder>lambdaUpdate().set(StoreOrder::getStatus, 0).eq(StoreOrder::getId, storeOrder.getId()));
            storeOrderInfoPickingService.update(Wrappers.<StoreOrderInfoPicking>lambdaUpdate().set(StoreOrderInfoPicking::getIsDel, 1).eq(StoreOrderInfoPicking::getOrderId, storeOrder.getId()));
            return orderInfoList;
        }
        return null;
    }


    public List<StoreOrderInfoVo> getOrderInfoVoList(StoreOrder storeOrder) {
        List<StoreOrderInfoVo> orderInfoVoList;
        if (Objects.equals(storeOrder.getStatus(), OrderStatusEnum.VERIFY.getCode())) {
            orderInfoVoList = storeOrderInfoService.getPickingOrderListByOrderId(storeOrder.getId());
        } else if (Objects.equals(storeOrder.getStatus(), OrderStatusEnum.CANCEL.getCode())) {
            orderInfoVoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
            if (CollectionUtils.isEmpty(orderInfoVoList)) {
                orderInfoVoList = storeOrderInfoService.getPickingOrderListByOrderId(storeOrder.getId());
            }
        } else {
            orderInfoVoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
        }
        return orderInfoVoList;
    }

    /**
     * 连连支付：担保确认
     * @date:  2022-08-01 13:45
     */
    public Map<String, Object> securedConfirm(StoreOrder order) {

        if(!"lianlian_degree".equals(order.getPayType())){
            log.info("当前订单的支付方式不是连连支付，订单号：{}", order.getOrderId());
            Map<String, Object> map = new HashMap<>();
            map.put("result", "SUCCESS");
            return map;
        }
        SecuredConfirmParams params = new SecuredConfirmParams();
        String timestamp = LLianPayDateUtils.getTimestamp();
        params.setTimestamp(timestamp);
        params.setOid_partner(Constants.OID_PARTNER_PROD_TUGOU);
        params.setUser_id(order.getUid() == null ? null : String.valueOf(order.getUid()));
        /*
        确认方式。
        ALL：全订单金额一次性确认（创单时指定了收款方）
        PART：订单金额部分多次确认
         */
        params.setConfirm_mode("ALL");

        // 原商户订单信息
        SecuredConfirmOriginalOrderInfo originalOrderInfo = new SecuredConfirmOriginalOrderInfo();
        // 原商户订单交易流水号
        originalOrderInfo.setTxn_seqno(order.getOrderId());
        // 原商户订单总金额
        originalOrderInfo.setTotal_amount(order.getPayPrice());
        params.setOriginalOrderInfo(originalOrderInfo);

        // 确认订单信息
        SecuredConfirmOrderInfo orderInfo = new SecuredConfirmOrderInfo();
        // 确认订单号
        LocalDateTime time = LocalDateTime.now();
        orderInfo.setConfirm_seqno(order.getOrderId() + time.getHour() + "" + time.getMinute() + "" + time.getSecond());
        orderInfo.setConfirm_time(timestamp);
        orderInfo.setConfirm_amount(order.getPayPrice());
        params.setConfirmOrderInfo(orderInfo);

        log.info("--------------- 连连支付担保确认入参: {}", JSON.toJSONString(params));
        LLianPayClient lLianPayClient = new LLianPayClient();
        String resultJsonStr = lLianPayClient.sendRequest(Constants.SECURED_CONFIRM_URL_PROD, JSON.toJSONString(params));
        log.info("--------------- 连连支付担保确认返回结果源数据: {}", JSON.toJSONString(resultJsonStr));
        DingTalkMsgUtil.sendMsg(DingMsgEnum.ORDER_PAY,"连连支付担保确认返回结果:"+JSON.toJSONString(resultJsonStr));


        SecuredConfirmResult response = JSON.parseObject(resultJsonStr, SecuredConfirmResult.class);

        String ret_code = response.getRet_code();
        String ret_msg = response.getRet_msg();
        String oid_partner = response.getOid_partner();
        String user_id = response.getUser_id();
        String txn_seqno = response.getTxn_seqno();
        String accp_txno = response.getAccp_txno();


        // 返回结果
        Map<String, Object> result = new HashMap<>();
        if ("0000".equals(ret_code)) {
            log.info("--------------- 连连支付担保确认成功!: {}", JSON.toJSONString(ret_msg));
            result.put("result", "SUCCESS");
        } else {
            result.put("result", ret_msg);
            log.error("--------------- 连连支付担保确认失败!: {}", JSON.toJSONString(ret_msg));
        }


        return result;
    }

}
